QuarkSocPkg: Add new package for Quark SoC X1000

Changes for V4
==============
1) Remove Unicode character from C source file
2) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode
   from QuarkPlatformPkg commit to QuarkSocPkg commit

Changes for V2
==============
1) Sync with new APIs in SmmCpuFeaturesLib class
2) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg
3) Remove PCI serial driver from QuarkSocPkg
4) Apply optimizations to MtrrLib from MtrrLib in UefiCpuPkg
5) Convert all UNI files to utf-8
6) Replace tabs with spaces and remove trailing spaces
7) Add License.txt

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Acked-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19286 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Michael Kinney
2015-12-15 19:22:23 +00:00
committed by mdkinney
parent 46ff196fde
commit 9b6bbcdbfd
176 changed files with 54761 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
/** @file
Header file for chipset CE-AT spec.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _CE_ATA_H
#define _CE_ATA_H
#pragma pack(1)
#define DATA_UNIT_SIZE 512
#define CMD60 60
#define CMD61 61
#define RW_MULTIPLE_REGISTER CMD60
#define RW_MULTIPLE_BLOCK CMD61
#define CE_ATA_SIG_CE 0xCE
#define CE_ATA_SIG_AA 0xAA
#define Reg_Features_Exp 01
#define Reg_SectorCount_Exp 02
#define Reg_LBALow_Exp 03
#define Reg_LBAMid_Exp 04
#define Reg_LBAHigh_Exp 05
#define Reg_Control 06
#define Reg_Features_Error 09
#define Reg_SectorCount 10
#define Reg_LBALow 11
#define Reg_LBAMid 12
#define Reg_LBAHigh 13
#define Reg_Device_Head 14
#define Reg_Command_Status 15
#define Reg_scrTempC 0x80
#define Reg_scrTempMaxP 0x84
#define Reg_scrTempMinP 0x88
#define Reg_scrStatus 0x8C
#define Reg_scrReallocsA 0x90
#define Reg_scrERetractsA 0x94
#define Reg_scrCapabilities 0x98
#define Reg_scrControl 0xC0
typedef struct {
UINT8 Reserved0;
UINT8 Features_Exp;
UINT8 SectorCount_Exp;
UINT8 LBALow_Exp;
UINT8 LBAMid_Exp;
UINT8 LBAHigh_Exp;
UINT8 Control;
UINT8 Reserved1[2];
UINT8 Features_Error;
UINT8 SectorCount;
UINT8 LBALow;
UINT8 LBAMid;
UINT8 LBAHigh;
UINT8 Device_Head;
UINT8 Command_Status;
}TASK_FILE;
//
//Reduced ATA command set
//
#define IDENTIFY_DEVICE 0xEC
#define READ_DMA_EXT 0x25
#define WRITE_DMA_EXT 0x35
#define STANDBY_IMMEDIATE 0xE0
#define FLUSH_CACHE_EXT 0xEA
typedef struct {
UINT16 Reserved0[10];
UINT16 SerialNumber[10];
UINT16 Reserved1[3];
UINT16 FirmwareRevision[4];
UINT16 ModelNumber[20];
UINT16 Reserved2[33];
UINT16 MajorVersion;
UINT16 Reserved3[19];
UINT16 MaximumLBA[4];
UINT16 Reserved4[2];
UINT16 Sectorsize;
UINT16 Reserved5;
UINT16 DeviceGUID[4];
UINT16 Reserved6[94];
UINT16 Features;
UINT16 MaxWritesPerAddress;
UINT16 Reserved7[47];
UINT16 IntegrityWord;
}IDENTIFY_DEVICE_DATA;
#pragma pack()
#endif

View File

@@ -0,0 +1,101 @@
/** @file
Include file for I2C DXE Driver register definitions (PCIe config. space and memory space).
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _I2C_REGS_H_
#define _I2C_REGS_H_
//----------------------------------------------------------------------------
/// I2C Device Address
//----------------------------------------------------------------------------
typedef struct {
///
/// The I2C hardware address to which the I2C device is preassigned or allocated.
///
UINTN I2CDeviceAddress : 10;
} EFI_I2C_DEVICE_ADDRESS;
//----------------------------------------------------------------------------
/// I2C Addressing Mode (7-bit or 10 bit)
//----------------------------------------------------------------------------
typedef enum _EFI_I2C_ADDR_MODE {
EfiI2CSevenBitAddrMode,
EfiI2CTenBitAddrMode,
} EFI_I2C_ADDR_MODE;
//----------------------------------------------------------------------------
// I2C Controller B:D:F
//----------------------------------------------------------------------------
#define I2C_Bus 0x00
#define I2C_Device 0x15
#define I2C_Func 0x02
//----------------------------------------------------------------------------
// Memory Mapped Registers
//----------------------------------------------------------------------------
#define I2C_REG_CON 0x00 // Control Register
#define B_I2C_REG_CON_SPEED (BIT2+BIT1) // standard mode (01) or fast mode (10)
#define B_I2C_REG_CON_10BITADD_MASTER (BIT4) // 7-bit addressing (0) or 10-bit addressing (1)
#define I2C_REG_TAR 0x04 // Master Target Address Register
#define B_I2C_REG_TAR (BIT9+BIT8+BIT7+BIT6+BIT5+BIT4+BIT3+BIT2+BIT1+BIT0) // Master Target Address bits
#define I2C_REG_DATA_CMD 0x10 // Data Buffer and Command Register
#define B_I2C_REG_DATA_CMD_RW (BIT8) // Data Buffer and Command Register Read/Write bit
#define B_I2C_REG_DATA_CMD_STOP (BIT9) // Data Buffer and Command Register STOP bit
#define B_I2C_REG_DATA_CMD_RESTART (BIT10) // Data Buffer and Command Register RESTART bit
#define I2C_REG_SS_SCL_HCNT 0x14 // Standard Speed Clock SCL High Count Register
#define I2C_REG_SS_SCL_LCNT 0x18 // Standard Speed Clock SCL Low Count Register
#define I2C_REG_FS_SCL_HCNT 0x1C // Fast Speed Clock SCL High Count Register
#define I2C_REG_FS_SCL_LCNT 0x20 // Fast Speed Clock SCL Low Count Register
#define I2C_REG_INTR_STAT 0x2C // Interrupt Status Register
#define B_I2C_REG_INTR_STAT_STOP_DET (BIT9) // Interrupt Status Register STOP_DET signal status
#define I2C_REG_INTR_MASK 0x30 // Interrupt Status Mask Register
#define I2C_REG_RAW_INTR_STAT 0x34 // Raw Interrupt Status Register
#define I2C_REG_RAW_INTR_STAT_STOP_DET (BIT9) // Raw Interrupt Status Register STOP_DET signal status.
#define I2C_REG_RAW_INTR_STAT_TX_ABRT (BIT6) // Raw Interrupt Status Register TX Abort status.
#define I2C_REG_RAW_INTR_STAT_TX_OVER (BIT3) // Raw Interrupt Status Register TX Overflow signal status.
#define I2C_REG_RAW_INTR_STAT_RX_OVER (BIT1) // Raw Interrupt Status Register RX Overflow signal status.
#define I2C_REG_RAW_INTR_STAT_RX_UNDER (BIT0) // Raw Interrupt Status Register RX Underflow signal status.
#define I2C_REG_RX_TL 0x38 // Receive FIFO Threshold Level Register
#define I2C_REG_TX_TL 0x3C // Transmit FIFO Threshold Level Register
#define I2C_REG_CLR_INT 0x40 // Clear Combined and Individual Interrupt Register
#define I2C_REG_CLR_RX_UNDER 0x44 // Clear RX Under Interrupt Register
#define I2C_REG_CLR_RX_OVER 0x48 // Clear RX Over Interrupt Register
#define I2C_REG_CLR_TX_OVER 0x4C // Clear TX Over Interrupt Register
#define I2C_REG_CLR_RD_REQ 0x50 // Clear RD REQ Interrupt Register
#define I2C_REG_CLR_TX_ABRT 0x54 // Clear TX ABRT Interrupt Register
#define I2C_REG_CLR_ACTIVITY 0x5C // Clear Activity Interrupt Register
#define I2C_REG_CLR_STOP_DET 0x60 // Clear STOP DET Interrupt Register
#define B_I2C_REG_CLR_STOP_DET (BIT0) // Clear STOP DET Interrupt Register
#define I2C_REG_CLR_START_DET 0x64 // Clear START DET Interrupt Register
#define B_I2C_REG_CLR_START_DET (BIT0) // Clear START DET Interrupt Register
#define I2C_REG_ENABLE 0x6C // Enable Register
#define B_I2C_REG_ENABLE (BIT0) // Enable (1) or disable (0) I2C Controller
#define I2C_REG_STATUS 0x70 // Status Register
#define I2C_REG_TXFLR 0x74 // Transmit FIFO Level Register
#define B_I2C_REG_TXFLR (BIT3+BIT2+BIT1+BIT0) // Transmit FIFO Level Register bits
#define I2C_REG_RXFLR 0x78 // Receive FIFO Level Register
#define B_I2C_REG_RXFLR (BIT3+BIT2+BIT1+BIT0) // Receive FIFO Level Register bits
#define I2C_REG_SDA_HOLD 0x7C // SDA HOLD Register
#define I2C_REG_TX_ABRT_SOURCE 0x80 // Transmit Abort Source Register
#define I2C_REG_ENABLE_STATUS 0x9C // Enable Status Register
#define I2C_REG_FS_SPKLEN 0xA0 // SS and FS Spike Suppression Limit Register
//
// Features.
//
#define I2C_FIFO_SIZE 16
#endif

View File

@@ -0,0 +1,254 @@
/** @file
Header file for QuarkSCSocId Ioh.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IOH_H_
#define _IOH_H_
#ifndef BIT0
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define BIT8 0x100
#define BIT9 0x200
#define BIT00 0x00000001
#define BIT01 0x00000002
#define BIT02 0x00000004
#define BIT03 0x00000008
#define BIT04 0x00000010
#define BIT05 0x00000020
#define BIT06 0x00000040
#define BIT07 0x00000080
#define BIT08 0x00000100
#define BIT09 0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
#endif
#define IOH_PCI_CFG_ADDRESS(bus,dev,func,reg) \
((UINT32) ( (((UINTN)bus) << 24) + (((UINTN)dev) << 16) + \
(((UINTN)func) << 8) + ((UINTN)reg) ))& 0x00000000ffffffff
//----------------------------------------------------------------------------
#define INTEL_VENDOR_ID 0x8086 // Intel Vendor ID
//----------------------------------------------------------------------------
// Pci Configuration Map Register Offsets
//----------------------------------------------------------------------------
#define PCI_REG_VID 0x00 // Vendor ID Register
#define PCI_REG_DID 0x02 // Device ID Register
#define PCI_REG_PCICMD 0x04 // PCI Command Register
#define PCI_REG_PCISTS 0x06 // PCI Status Register
#define PCI_REG_RID 0x08 // PCI Revision ID Register
#define PCI_REG_PI 0x09 // Programming Interface
#define PCI_REG_SCC 0x0a // Sub Class Code Register
#define PCI_REG_BCC 0x0b // Base Class Code Register
#define PCI_REG_PMLT 0x0d // Primary Master Latnecy Timer
#define PCI_REG_HDR 0x0e // Header Type Register
#define PCI_REG_PBUS 0x18 // Primary Bus Number Register
#define PCI_REG_SBUS 0x19 // Secondary Bus Number Register
#define PCI_REG_SUBUS 0x1a // Subordinate Bus Number Register
#define PCI_REG_SMLT 0x1b // Secondary Master Latnecy Timer
#define PCI_REG_IOBASE 0x1c // I/O base Register
#define PCI_REG_IOLIMIT 0x1d // I/O Limit Register
#define PCI_REG_SECSTATUS 0x1e // Secondary Status Register
#define PCI_REG_MEMBASE 0x20 // Memory Base Register
#define PCI_REG_MEMLIMIT 0x22 // Memory Limit Register
#define PCI_REG_PRE_MEMBASE 0x24 // Prefretchable memory Base register
#define PCI_REG_PRE_MEMLIMIT 0x26 // Prefretchable memory Limit register
#define PCI_REG_SVID0 0x2c // Subsystem Vendor ID low byte
#define PCI_REG_SVID1 0x2d // Subsystem Vendor ID high byte
#define PCI_REG_SID0 0x2e // Subsystem ID low byte
#define PCI_REG_SID1 0x2f // Subsystem ID high byte
#define PCI_REG_IOBASE_U 0x30 // I/O base Upper Register
#define PCI_REG_IOLIMIT_U 0x32 // I/O Limit Upper Register
#define PCI_REG_INTLINE 0x3c // Interrupt Line Register
#define PCI_REG_BRIDGE_CNTL 0x3e // Bridge Control Register
//---------------------------------------------------------------------------
// QuarkSCSocId Packet Hub definitions
//---------------------------------------------------------------------------
#define PCIE_BRIDGE_VID_DID 0x88008086
//---------------------------------------------------------------------------
// Quark South Cluster definitions.
//---------------------------------------------------------------------------
#define IOH_BUS 0
#define IOH_PCI_IOSF2AHB_0_DEV_NUM 0x14
#define IOH_PCI_IOSF2AHB_0_MAX_FUNCS 7
#define IOH_PCI_IOSF2AHB_1_DEV_NUM 0x15
#define IOH_PCI_IOSF2AHB_1_MAX_FUNCS 3
//---------------------------------------------------------------------------
// Quark South Cluster USB definitions.
//---------------------------------------------------------------------------
#define IOH_USB_BUS_NUMBER IOH_BUS
#define IOH_USB_CONTROLLER_MMIO_RANGE 0x1000
#define IOH_MAX_OHCI_USB_CONTROLLERS 1
#define IOH_MAX_EHCI_USB_CONTROLLERS 1
#define IOH_MAX_USBDEVICE_USB_CONTROLLERS 1
#define R_IOH_USB_VENDOR_ID 0x00
#define V_IOH_USB_VENDOR_ID INTEL_VENDOR_ID
#define R_IOH_USB_DEVICE_ID 0x02
#define R_IOH_USB_COMMAND 0x04
#define B_IOH_USB_COMMAND_BME BIT2
#define B_IOH_USB_COMMAND_MSE BIT1
#define B_IOH_USB_COMMAND_ISE BIT0
#define R_IOH_USB_MEMBAR 0x10
#define B_IOH_USB_MEMBAR_ADDRESS_MASK 0xFFFFF000 // [31:12].
#define R_IOH_USB_OHCI_HCCABAR 0x18
//---------------------------------------------------------------------------
// Quark South Cluster OHCI definitions
//---------------------------------------------------------------------------
#define IOH_USB_OHCI_DEVICE_NUMBER IOH_PCI_IOSF2AHB_0_DEV_NUM
#define IOH_OHCI_FUNCTION_NUMBER 0x04
//---------------------------------------------------------------------------
// Quark South Cluster EHCI definitions
//---------------------------------------------------------------------------
#define IOH_USB_EHCI_DEVICE_NUMBER IOH_PCI_IOSF2AHB_0_DEV_NUM
#define IOH_EHCI_FUNCTION_NUMBER 0x03
//
// EHCI memory mapped registers offset from memory BAR0.
//
#define R_IOH_EHCI_CAPLENGTH 0x00
#define R_IOH_EHCI_INSNREG01 0x94
#define B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP (16)
#define B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_MASK (0xff << B_IOH_EHCI_INSNREG01_OUT_THRESHOLD_BP)
#define B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP (0)
#define B_IOH_EHCI_INSNREG01_IN_THRESHOLD_MASK (0xff << B_IOH_EHCI_INSNREG01_IN_THRESHOLD_BP)
//
// EHCI memory mapped registers offset from memory BAR0 + Cap length value.
//
#define R_IOH_EHCI_CONFIGFLAGS 0x40
//---------------------------------------------------------------------------
// Quark South Cluster USB Device definitions
//---------------------------------------------------------------------------
#define IOH_USBDEVICE_DEVICE_NUMBER IOH_PCI_IOSF2AHB_0_DEV_NUM
#define IOH_USBDEVICE_FUNCTION_NUMBER 0x02
//
// USB Device memory mapped registers offset from memory BAR0.
//
#define R_IOH_USBDEVICE_D_INTR_UDC_REG 0x40c
#define R_IOH_USBDEVICE_D_INTR_MSK_UDC_REG 0x410
#define B_IOH_USBDEVICE_D_INTR_MSK_UDC_REG_MASK1_MASK 0xff
#define R_IOH_USBDEVICE_EP_INTR_UDC_REG 0x414
#define R_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG 0x418
#define B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_OUT_EP_MASK 0x000f0000
#define B_IOH_USBDEVICE_EP_INTR_MSK_UDC_REG_IN_EP_MASK 0x0000000f
//---------------------------------------------------------------------------
// Quark South Cluster 10/100 Mbps Ethernet Device definitions.
//---------------------------------------------------------------------------
#define IOH_MAC0_BUS_NUMBER IOH_BUS
#define IOH_MAC0_DEVICE_NUMBER IOH_PCI_IOSF2AHB_0_DEV_NUM
#define IOH_MAC0_FUNCTION_NUMBER 0x06
#define IOH_MAC1_BUS_NUMBER IOH_BUS
#define IOH_MAC1_DEVICE_NUMBER IOH_PCI_IOSF2AHB_0_DEV_NUM
#define IOH_MAC1_FUNCTION_NUMBER 0x07
//
// MAC Device PCI config registers.
//
#define R_IOH_MAC_DEVICE_ID 0x02
#define V_IOH_MAC_VENDOR_ID INTEL_VENDOR_ID
#define R_IOH_MAC_DEVICE_ID 0x02
#define V_IOH_MAC_DEVICE_ID 0x0937
#define R_IOH_MAC_COMMAND 0x04
#define B_IOH_MAC_COMMAND_BME BIT2
#define B_IOH_MAC_COMMAND_MSE BIT1
#define B_IOH_MAC_COMMAND_ISE BIT0
#define R_IOH_MAC_MEMBAR 0x10
#define B_IOH_MAC_MEMBAR_ADDRESS_MASK 0xFFFFF000
//
// LAN Device memory mapped registers offset from memory BAR0.
//
#define R_IOH_MAC_GMAC_REG_8 0x20
#define B_IOH_MAC_USERVER_MASK 0x0000FF00
#define B_IOH_MAC_SNPSVER_MASK 0x000000FF
#define R_IOH_MAC_GMAC_REG_16 0x40
#define B_IOH_MAC_ADDRHI_MASK 0x0000FFFF
#define B_IOH_MAC_AE BIT31
#define R_IOH_MAC_GMAC_REG_17 0x44
#define B_IOH_MAC_ADDRLO_MASK 0xFFFFFFFF
//---------------------------------------------------------------------------
// Quark I2C / GPIO definitions
//---------------------------------------------------------------------------
#define V_IOH_I2C_GPIO_VENDOR_ID INTEL_VENDOR_ID
#define V_IOH_I2C_GPIO_DEVICE_ID 0x0934
#define R_IOH_I2C_MEMBAR 0x10
#define B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK 0xFFFFF000 // [31:12].
#define GPIO_SWPORTA_DR 0x00
#define GPIO_SWPORTA_DDR 0x04
#define GPIO_INTEN 0x30
#define GPIO_INTMASK 0x34
#define GPIO_INTTYPE_LEVEL 0x38
#define GPIO_INT_POLARITY 0x3C
#define GPIO_INTSTATUS 0x40
#define GPIO_RAW_INTSTATUS 0x44
#define GPIO_DEBOUNCE 0x48
#define GPIO_PORTA_EOI 0x4C
#define GPIO_EXT_PORTA 0x50
#define GPIO_EXT_PORTB 0x54
#define GPIO_LS_SYNC 0x60
#define GPIO_CONFIG_REG2 0x70
#define GPIO_CONFIG_REG1 0x74
//---------------------------------------------------------------------------
// Quark South Cluster UART definitions.
//---------------------------------------------------------------------------
#define R_IOH_UART_MEMBAR 0x10
#define B_IOH_UART_MEMBAR_ADDRESS_MASK 0xFFFFF000 // [31:12].
#endif

View File

@@ -0,0 +1,24 @@
/** @file
Macros to simplify and abstract the interface to PCI configuration.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IOH_ACCESS_H_
#define _IOH_ACCESS_H_
#include "Ioh.h"
#include "IohCommonDefinitions.h"
#endif

View File

@@ -0,0 +1,348 @@
/** @file
This header file provides common definitions just for MCH using to avoid including extra module's file.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IOH_COMMON_DEFINITIONS_H_
#define _IOH_COMMON_DEFINITIONS_H_
//
// PCI CONFIGURATION MAP REGISTER OFFSETS
//
#ifndef PCI_VID
#define PCI_VID 0x0000 // Vendor ID Register
#define PCI_DID 0x0002 // Device ID Register
#define PCI_CMD 0x0004 // PCI Command Register
#define PCI_STS 0x0006 // PCI Status Register
#define PCI_RID 0x0008 // Revision ID Register
#define PCI_IFT 0x0009 // Interface Type
#define PCI_SCC 0x000A // Sub Class Code Register
#define PCI_BCC 0x000B // Base Class Code Register
#define PCI_CLS 0x000C // Cache Line Size
#define PCI_PMLT 0x000D // Primary Master Latency Timer
#define PCI_HDR 0x000E // Header Type Register
#define PCI_BIST 0x000F // Built in Self Test Register
#define PCI_BAR0 0x0010 // Base Address Register 0
#define PCI_BAR1 0x0014 // Base Address Register 1
#define PCI_BAR2 0x0018 // Base Address Register 2
#define PCI_PBUS 0x0018 // Primary Bus Number Register
#define PCI_SBUS 0x0019 // Secondary Bus Number Register
#define PCI_SUBUS 0x001A // Subordinate Bus Number Register
#define PCI_SMLT 0x001B // Secondary Master Latency Timer
#define PCI_BAR3 0x001C // Base Address Register 3
#define PCI_IOBASE 0x001C // I/O base Register
#define PCI_IOLIMIT 0x001D // I/O Limit Register
#define PCI_SECSTATUS 0x001E // Secondary Status Register
#define PCI_BAR4 0x0020 // Base Address Register 4
#define PCI_MEMBASE 0x0020 // Memory Base Register
#define PCI_MEMLIMIT 0x0022 // Memory Limit Register
#define PCI_BAR5 0x0024 // Base Address Register 5
#define PCI_PRE_MEMBASE 0x0024 // Prefetchable memory Base register
#define PCI_PRE_MEMLIMIT 0x0026 // Prefetchable memory Limit register
#define PCI_PRE_MEMBASE_U 0x0028 // Prefetchable memory base upper 32 bits
#define PCI_PRE_MEMLIMIT_U 0x002C // Prefetchable memory limit upper 32 bits
#define PCI_SVID 0x002C // Subsystem Vendor ID
#define PCI_SID 0x002E // Subsystem ID
#define PCI_IOBASE_U 0x0030 // I/O base Upper Register
#define PCI_IOLIMIT_U 0x0032 // I/O Limit Upper Register
#define PCI_CAPP 0x0034 // Capabilities Pointer
#define PCI_EROM 0x0038 // Expansion ROM Base Address
#define PCI_INTLINE 0x003C // Interrupt Line Register
#define PCI_INTPIN 0x003D // Interrupt Pin Register
#define PCI_MAXGNT 0x003E // Max Grant Register
#define PCI_BRIDGE_CNTL 0x003E // Bridge Control Register
#define PCI_MAXLAT 0x003F // Max Latency Register
#endif
//
// Bit Difinitions
//
#ifndef BIT0
#define BIT0 0x0001
#define BIT1 0x0002
#define BIT2 0x0004
#define BIT3 0x0008
#define BIT4 0x0010
#define BIT5 0x0020
#define BIT6 0x0040
#define BIT7 0x0080
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
#endif
//
// Common Memory mapped Io access macros ------------------------------------------
//
#define IohMmioAddress( BaseAddr, Register ) \
( (UINTN)BaseAddr + \
(UINTN)(Register) \
)
//
// UINT64
//
#define IohMmio64Ptr( BaseAddr, Register ) \
( (volatile UINT64 *)IohMmioAddress( BaseAddr, Register ) )
#define IohMmio64( BaseAddr, Register ) \
*IohMmio64Ptr( BaseAddr, Register )
#define IohMmio64Or( BaseAddr, Register, OrData ) \
IohMmio64( BaseAddr, Register ) = \
(UINT64) ( \
IohMmio64( BaseAddr, Register ) | \
(UINT64)(OrData) \
)
#define IohMmio64And( BaseAddr, Register, AndData ) \
IohMmio64( BaseAddr, Register ) = \
(UINT64) ( \
IohMmio64( BaseAddr, Register ) & \
(UINT64)(AndData) \
)
#define IohMmio64AndThenOr( BaseAddr, Register, AndData, OrData ) \
IohMmio64( BaseAddr, Register ) = \
(UINT64) ( \
( IohMmio64( BaseAddr, Register ) & \
(UINT64)(AndData) \
) | \
(UINT64)(OrData) \
)
//
// UINT32
//
#define IohMmio32Ptr( BaseAddr, Register ) \
( (volatile UINT32 *)IohMmioAddress( BaseAddr, Register ) )
#define IohMmio32( BaseAddr, Register ) \
*IohMmio32Ptr( BaseAddr, Register )
#define IohMmio32Or( BaseAddr, Register, OrData ) \
IohMmio32( BaseAddr, Register ) = \
(UINT32) ( \
IohMmio32( BaseAddr, Register ) | \
(UINT32)(OrData) \
)
#define IohMmio32And( BaseAddr, Register, AndData ) \
IohMmio32( BaseAddr, Register ) = \
(UINT32) ( \
IohMmio32( BaseAddr, Register ) & \
(UINT32)(AndData) \
)
#define IohMmio32AndThenOr( BaseAddr, Register, AndData, OrData ) \
IohMmio32( BaseAddr, Register ) = \
(UINT32) ( \
( IohMmio32( BaseAddr, Register ) & \
(UINT32)(AndData) \
) | \
(UINT32)(OrData) \
)
//
// UINT16
//
#define IohMmio16Ptr( BaseAddr, Register ) \
( (volatile UINT16 *)IohMmioAddress( BaseAddr, Register ) )
#define IohMmio16( BaseAddr, Register ) \
*IohMmio16Ptr( BaseAddr, Register )
#define IohMmio16Or( BaseAddr, Register, OrData ) \
IohMmio16( BaseAddr, Register ) = \
(UINT16) ( \
IohMmio16( BaseAddr, Register ) | \
(UINT16)(OrData) \
)
#define IohMmio16And( BaseAddr, Register, AndData ) \
IohMmio16( BaseAddr, Register ) = \
(UINT16) ( \
IohMmio16( BaseAddr, Register ) & \
(UINT16)(AndData) \
)
#define IohMmio16AndThenOr( BaseAddr, Register, AndData, OrData ) \
IohMmio16( BaseAddr, Register ) = \
(UINT16) ( \
( IohMmio16( BaseAddr, Register ) & \
(UINT16)(AndData) \
) | \
(UINT16)(OrData) \
)
//
// UINT8
//
#define IohMmio8Ptr( BaseAddr, Register ) \
( (volatile UINT8 *)IohMmioAddress( BaseAddr, Register ) )
#define IohMmio8( BaseAddr, Register ) \
*IohMmio8Ptr( BaseAddr, Register )
#define IohMmio8Or( BaseAddr, Register, OrData ) \
IohMmio8( BaseAddr, Register ) = \
(UINT8) ( \
IohMmio8( BaseAddr, Register ) | \
(UINT8)(OrData) \
)
#define IohMmio8And( BaseAddr, Register, AndData ) \
IohMmio8( BaseAddr, Register ) = \
(UINT8) ( \
IohMmio8( BaseAddr, Register ) & \
(UINT8)(AndData) \
)
#define IohMmio8AndThenOr( BaseAddr, Register, AndData, OrData ) \
IohMmio8( BaseAddr, Register ) = \
(UINT8) ( \
( IohMmio8( BaseAddr, Register ) & \
(UINT8)(AndData) \
) | \
(UINT8)(OrData) \
)
//
// Common Memory mapped Pci access macros ------------------------------------------
//
#define Ioh_PCI_EXPRESS_BASE_ADDRESS 0xE0000000
#define IohMmPciAddress( Segment, Bus, Device, Function, Register ) \
( (UINTN)Ioh_PCI_EXPRESS_BASE_ADDRESS + \
(UINTN)(Bus << 20) + \
(UINTN)(Device << 15) + \
(UINTN)(Function << 12) + \
(UINTN)(Register) \
)
//
// UINT32
//
#define IohMmPci32Ptr( Segment, Bus, Device, Function, Register ) \
( (volatile UINT32 *)IohMmPciAddress( Segment, Bus, Device, Function, Register ) )
#define IohMmPci32( Segment, Bus, Device, Function, Register ) \
*IohMmPci32Ptr( Segment, Bus, Device, Function, Register )
#define IohMmPci32Or( Segment, Bus, Device, Function, Register, OrData ) \
IohMmPci32( Segment, Bus, Device, Function, Register ) = \
(UINT32) ( \
IohMmPci32( Segment, Bus, Device, Function, Register ) | \
(UINT32)(OrData) \
)
#define IohMmPci32And( Segment, Bus, Device, Function, Register, AndData ) \
IohMmPci32( Segment, Bus, Device, Function, Register ) = \
(UINT32) ( \
IohMmPci32( Segment, Bus, Device, Function, Register ) & \
(UINT32)(AndData) \
)
#define IohMmPci32AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
IohMmPci32( Segment, Bus, Device, Function, Register ) = \
(UINT32) ( \
( IohMmPci32( Segment, Bus, Device, Function, Register ) & \
(UINT32)(AndData) \
) | \
(UINT32)(OrData) \
)
//
// UINT16
//
#define IohMmPci16Ptr( Segment, Bus, Device, Function, Register ) \
( (volatile UINT16 *)IohMmPciAddress( Segment, Bus, Device, Function, Register ) )
#define IohMmPci16( Segment, Bus, Device, Function, Register ) \
*IohMmPci16Ptr( Segment, Bus, Device, Function, Register )
#define IohMmPci16Or( Segment, Bus, Device, Function, Register, OrData ) \
IohMmPci16( Segment, Bus, Device, Function, Register ) = \
(UINT16) ( \
IohMmPci16( Segment, Bus, Device, Function, Register ) | \
(UINT16)(OrData) \
)
#define IohMmPci16And( Segment, Bus, Device, Function, Register, AndData ) \
IohMmPci16( Segment, Bus, Device, Function, Register ) = \
(UINT16) ( \
IohMmPci16( Segment, Bus, Device, Function, Register ) & \
(UINT16)(AndData) \
)
#define IohMmPci16AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
IohMmPci16( Segment, Bus, Device, Function, Register ) = \
(UINT16) ( \
( IohMmPci16( Segment, Bus, Device, Function, Register ) & \
(UINT16)(AndData) \
) | \
(UINT16)(OrData) \
)
//
// UINT8
//
#define IohMmPci8Ptr( Segment, Bus, Device, Function, Register ) \
( (volatile UINT8 *)IohMmPciAddress( Segment, Bus, Device, Function, Register ) )
#define IohMmPci8( Segment, Bus, Device, Function, Register ) \
*IohMmPci8Ptr( Segment, Bus, Device, Function, Register )
#define IohMmPci8Or( Segment, Bus, Device, Function, Register, OrData ) \
IohMmPci8( Segment, Bus, Device, Function, Register ) = \
(UINT8) ( \
IohMmPci8( Segment, Bus, Device, Function, Register ) | \
(UINT8)(OrData) \
)
#define IohMmPci8And( Segment, Bus, Device, Function, Register, AndData ) \
IohMmPci8( Segment, Bus, Device, Function, Register ) = \
(UINT8) ( \
IohMmPci8( Segment, Bus, Device, Function, Register ) & \
(UINT8)(AndData) \
)
#define IohMmPci8AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \
IohMmPci8( Segment, Bus, Device, Function, Register ) = \
(UINT8) ( \
( IohMmPci8( Segment, Bus, Device, Function, Register ) & \
(UINT8)(AndData) \
) | \
(UINT8)(OrData) \
)
#endif

View File

@@ -0,0 +1,158 @@
/** @file
Intel I2C library implementation built upon I/O library
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _I2C_LIB_H_
#define _I2C_LIB_H_
#include "I2cRegs.h"
/**
The I2cWriteByte() function is a wrapper function for the WriteByte() function.
Provides a standard way to execute a standard single byte write to an IC2 device
(without accessing sub-addresses), as defined in the I2C Specification.
@param SlaveAddress The I2C slave address of the device
with which to communicate.
@param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
@param Buffer Contains the value of byte data to execute to the
I2C slave device.
@retval EFI_SUCCESS Transfer success.
@retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid.
@retval EFI_TIMEOUT Timeout while waiting xfer.
@retval EFI_ABORTED Controller aborted xfer.
@retval EFI_DEVICE_ERROR Device error detected by controller.
**/
EFI_STATUS
EFIAPI
I2cWriteByte (
IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,
IN EFI_I2C_ADDR_MODE AddrMode,
IN OUT VOID *Buffer
);
/**
The I2cReadByte() function is a wrapper function for the ReadByte() function.
Provides a standard way to execute a standard single byte read to an I2C device
(without accessing sub-addresses), as defined in the I2C Specification.
@param SlaveAddress The I2C slave address of the device
with which to communicate.
@param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
@param Buffer Contains the value of byte data read from the
I2C slave device.
@retval EFI_SUCCESS Transfer success.
@retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid.
@retval EFI_TIMEOUT Timeout while waiting xfer.
@retval EFI_ABORTED Controller aborted xfer.
@retval EFI_DEVICE_ERROR Device error detected by controller.
**/
EFI_STATUS
EFIAPI
I2cReadByte (
IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,
IN EFI_I2C_ADDR_MODE AddrMode,
IN OUT VOID *Buffer
);
/**
The I2cWriteMultipleByte() function is a wrapper function for the WriteMultipleByte()
function. Provides a standard way to execute multiple byte writes to an I2C device (e.g. when
accessing sub-addresses or writing block of data), as defined in the I2C Specification.
@param SlaveAddress The I2C slave address of the device
with which to communicate.
@param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
@param Length No. of bytes to be written.
@param Buffer Contains the value of byte to be written to the
I2C slave device.
@retval EFI_SUCCESS Transfer success.
@retval EFI_INVALID_PARAMETER This, Length or Buffer pointers are invalid.
@retval EFI_UNSUPPORTED Unsupported input param.
@retval EFI_TIMEOUT Timeout while waiting xfer.
@retval EFI_ABORTED Controller aborted xfer.
@retval EFI_DEVICE_ERROR Device error detected by controller.
**/
EFI_STATUS
EFIAPI
I2cWriteMultipleByte (
IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,
IN EFI_I2C_ADDR_MODE AddrMode,
IN UINTN *Length,
IN OUT VOID *Buffer
);
/**
The I2cReadMultipleByte() function is a wrapper function for the ReadMultipleByte
function. Provides a standard way to execute multiple byte writes to an IC2 device
(e.g. when accessing sub-addresses or when reading block of data), as defined
in the I2C Specification (I2C combined write/read protocol).
@param SlaveAddress The I2C slave address of the device
with which to communicate.
@param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
@param WriteLength No. of bytes to be written. In this case data
written typically contains sub-address or sub-addresses
in Hi-Lo format, that need to be read (I2C combined
write/read protocol).
@param ReadLength No. of bytes to be read from I2C slave device.
need to be read.
@param Buffer Contains the value of byte data read from the
I2C slave device.
@retval EFI_SUCCESS Transfer success.
@retval EFI_INVALID_PARAMETER This, WriteLength, ReadLength or Buffer
pointers are invalid.
@retval EFI_UNSUPPORTED Unsupported input param.
@retval EFI_TIMEOUT Timeout while waiting xfer.
@retval EFI_ABORTED Controller aborted xfer.
@retval EFI_DEVICE_ERROR Device error detected by controller.
**/
EFI_STATUS
EFIAPI
I2cReadMultipleByte (
IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,
IN EFI_I2C_ADDR_MODE AddrMode,
IN UINTN *WriteLength,
IN UINTN *ReadLength,
IN OUT VOID *Buffer
);
#endif

View File

@@ -0,0 +1,42 @@
/** @file
Library that provides Soc specific library services for SouthCluster devices.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __IOH_LIB_H__
#define __IOH_LIB_H__
#include "Ioh.h"
EFI_STATUS
EFIAPI
InitializeIohSsvidSsid (
IN UINT8 Bus,
IN UINT8 Device,
IN UINT8 Func
);
VOID
EFIAPI
EnableUsbMemIoBusMaster (
IN UINT8 UsbBusNumber
);
UINT32
EFIAPI
ReadIohGpioValues (
VOID
);
#endif

View File

@@ -0,0 +1,280 @@
/** @file
Header file for Industry MMC 4.2 spec.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _MMC_H
#define _MMC_H
#pragma pack(1)
//
//Command definition
//
#define CMD0 0
#define CMD1 1
#define CMD2 2
#define CMD3 3
#define CMD4 4
#define CMD6 6
#define CMD7 7
#define CMD8 8
#define CMD9 9
#define CMD10 10
#define CMD11 11
#define CMD12 12
#define CMD13 13
#define CMD14 14
#define CMD15 15
#define CMD16 16
#define CMD17 17
#define CMD18 18
#define CMD19 19
#define CMD20 20
#define CMD23 23
#define CMD24 24
#define CMD25 25
#define CMD26 26
#define CMD27 27
#define CMD28 28
#define CMD29 29
#define CMD30 30
#define CMD35 35
#define CMD36 36
#define CMD38 38
#define CMD39 39
#define CMD40 40
#define CMD42 42
#define CMD55 55
#define CMD56 56
#define GO_IDLE_STATE CMD0
#define SEND_OP_COND CMD1
#define ALL_SEND_CID CMD2
#define SET_RELATIVE_ADDR CMD3
#define SET_DSR CMD4
#define SWITCH CMD6
#define SELECT_DESELECT_CARD CMD7
#define SEND_EXT_CSD CMD8
#define SEND_CSD CMD9
#define SEND_CID CMD10
#define READ_DAT_UNTIL_STOP CMD11
#define STOP_TRANSMISSION CMD12
#define SEND_STATUS CMD13
#define BUSTEST_R CMD14
#define GO_INACTIVE_STATE CMD15
#define SET_BLOCKLEN CMD16
#define READ_SINGLE_BLOCK CMD17
#define READ_MULTIPLE_BLOCK CMD18
#define BUSTEST_W CMD19
#define WRITE_DAT_UNTIL_STOP CMD20
#define SET_BLOCK_COUNT CMD23
#define WRITE_BLOCK CMD24
#define WRITE_MULTIPLE_BLOCK CMD25
#define PROGRAM_CID CMD26
#define PROGRAM_CSD CMD27
#define SET_WRITE_PROT CMD28
#define CLR_WRITE_PROT CMD29
#define SEND_WRITE_PROT CMD30
#define ERASE_GROUP_START CMD35
#define ERASE_GROUP_END CMD36
#define ERASE CMD38
#define FAST_IO CMD39
#define GO_IRQ_STATE CMD40
#define LOCK_UNLOCK CMD42
#define APP_CMD CMD55
#define GEN_CMD CMD56
#define CMD_INDEX_MASK 0x3F
#define AUTO_CMD12_ENABLE BIT6
#define AUTO_CMD23_ENABLE BIT7
#define FREQUENCY_OD (400 * 1000)
#define FREQUENCY_MMC_PP (26 * 1000 * 1000)
#define FREQUENCY_MMC_PP_HIGH (52 * 1000 * 1000)
#define DEFAULT_DSR_VALUE 0x404
//
//Registers definition
//
typedef struct {
UINT32 Reserved0: 7; // 0
UINT32 V170_V195: 1; // 1.70V - 1.95V
UINT32 V200_V260: 7; // 2.00V - 2.60V
UINT32 V270_V360: 9; // 2.70V - 3.60V
UINT32 Reserved1: 5; // 0
UINT32 AccessMode: 2; // 00b (byte mode), 10b (sector mode)
UINT32 Busy: 1; // This bit is set to LOW if the card has not finished the power up routine
}OCR;
typedef struct {
UINT8 NotUsed: 1; // 1
UINT8 CRC: 7; // CRC7 checksum
UINT8 MDT; // Manufacturing date
UINT32 PSN; // Product serial number
UINT8 PRV; // Product revision
UINT8 PNM[6]; // Product name
UINT16 OID; // OEM/Application ID
UINT8 MID; // Manufacturer ID
}CID;
typedef struct {
UINT8 NotUsed: 1; // 1 [0:0]
UINT8 CRC: 7; // CRC [7:1]
UINT8 ECC: 2; // ECC code [9:8]
UINT8 FILE_FORMAT: 2; // File format [11:10]
UINT8 TMP_WRITE_PROTECT: 1; // Temporary write protection [12:12]
UINT8 PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
UINT8 COPY: 1; // Copy flag (OTP) [14:14]
UINT8 FILE_FORMAT_GRP: 1; // File format group [15:15]
UINT16 CONTENT_PROT_APP: 1; // Content protection application [16:16]
UINT16 Reserved0: 4; // 0 [20:17]
UINT16 WRITE_BL_PARTIAL: 1; // Partial blocks for write allowed [21:21]
UINT16 WRITE_BL_LEN: 4; // Max. write data block length [25:22]
UINT16 R2W_FACTOR: 3; // Write speed factor [28:26]
UINT16 DEFAULT_ECC: 2; // Manufacturer default ECC [30:29]
UINT16 WP_GRP_ENABLE: 1; // Write protect group enable [31:31]
UINT32 WP_GRP_SIZE: 5; // Write protect group size [36:32]
UINT32 ERASE_GRP_MULT: 5; // Erase group size multiplier [41:37]
UINT32 ERASE_GRP_SIZE: 5; // Erase group size [46:42]
UINT32 C_SIZE_MULT: 3; // Device size multiplier [49:47]
UINT32 VDD_W_CURR_MAX: 3; // Max. write current @ VDD max [52:50]
UINT32 VDD_W_CURR_MIN: 3; // Max. write current @ VDD min [55:53]
UINT32 VDD_R_CURR_MAX: 3; // Max. read current @ VDD max [58:56]
UINT32 VDD_R_CURR_MIN: 3; // Max. read current @ VDD min [61:59]
UINT32 C_SIZELow2: 2;// Device size [73:62]
UINT32 C_SIZEHigh10: 10;// Device size [73:62]
UINT32 Reserved1: 2; // 0 [75:74]
UINT32 DSR_IMP: 1; // DSR implemented [76:76]
UINT32 READ_BLK_MISALIGN: 1; // Read block misalignment [77:77]
UINT32 WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
UINT32 READ_BL_PARTIAL: 1; // Partial blocks for read allowed [79:79]
UINT32 READ_BL_LEN: 4; // Max. read data block length [83:80]
UINT32 CCC: 12;// Card command classes [95:84]
UINT8 TRAN_SPEED ; // Max. bus clock frequency [103:96]
UINT8 NSAC ; // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
UINT8 TAAC ; // Data read access-time 1 [119:112]
UINT8 Reserved2: 2; // 0 [121:120]
UINT8 SPEC_VERS: 4; // System specification version [125:122]
UINT8 CSD_STRUCTURE: 2; // CSD structure [127:126]
}CSD;
typedef struct {
UINT8 Reserved0[181]; // 0 [0:180]
UINT8 ERASED_MEM_CONT; // Erased Memory Content [181]
UINT8 Reserved2; // Erased Memory Content [182]
UINT8 BUS_WIDTH; // Bus Width Mode [183]
UINT8 Reserved3; // 0 [184]
UINT8 HS_TIMING; // High Speed Interface Timing [185]
UINT8 Reserved4; // 0 [186]
UINT8 POWER_CLASS; // Power Class [187]
UINT8 Reserved5; // 0 [188]
UINT8 CMD_SET_REV; // Command Set Revision [189]
UINT8 Reserved6; // 0 [190]
UINT8 CMD_SET; // Command Set [191]
UINT8 EXT_CSD_REV; // Extended CSD Revision [192]
UINT8 Reserved7; // 0 [193]
UINT8 CSD_STRUCTURE; // CSD Structure Version [194]
UINT8 Reserved8; // 0 [195]
UINT8 CARD_TYPE; // Card Type [196]
UINT8 Reserved9[3]; // 0 [199:197]
UINT8 PWR_CL_52_195; // Power Class for 52MHz @ 1.95V [200]
UINT8 PWR_CL_26_195; // Power Class for 26MHz @ 1.95V [201]
UINT8 PWR_CL_52_360; // Power Class for 52MHz @ 3.6V [202]
UINT8 PWR_CL_26_360; // Power Class for 26MHz @ 3.6V [203]
UINT8 Reserved10; // 0 [204]
UINT8 MIN_PERF_R_4_26; // Minimum Read Performance for 4bit @26MHz [205]
UINT8 MIN_PERF_W_4_26; // Minimum Write Performance for 4bit @26MHz [206]
UINT8 MIN_PERF_R_8_26_4_52; // Minimum Read Performance for 8bit @26MHz/4bit @52MHz [207]
UINT8 MIN_PERF_W_8_26_4_52; // Minimum Write Performance for 8bit @26MHz/4bit @52MHz [208]
UINT8 MIN_PERF_R_8_52; // Minimum Read Performance for 8bit @52MHz [209]
UINT8 MIN_PERF_W_8_52; // Minimum Write Performance for 8bit @52MHz [210]
UINT8 Reserved11; // 0 [211]
UINT8 SEC_COUNT[4]; // Sector Count [215:212]
UINT8 Reserved12[288]; // 0 [503:216]
UINT8 S_CMD_SET; // Sector Count [504]
UINT8 Reserved13[7]; // Sector Count [511:505]
}EXT_CSD;
//
//Card Status definition
//
typedef struct {
UINT32 Reserved0: 2; //Reserved for Manufacturer Test Mode
UINT32 Reserved1: 2; //Reserved for Application Specific commands
UINT32 Reserved2: 1; //
UINT32 SAPP_CMD: 1; //
UINT32 Reserved3: 1; //Reserved
UINT32 SWITCH_ERROR: 1; //
UINT32 READY_FOR_DATA: 1; //
UINT32 CURRENT_STATE: 4; //
UINT32 ERASE_RESET: 1; //
UINT32 Reserved4: 1; //Reserved
UINT32 WP_ERASE_SKIP: 1; //
UINT32 CID_CSD_OVERWRITE: 1; //
UINT32 OVERRUN: 1; //
UINT32 UNDERRUN: 1; //
UINT32 ERROR: 1; //
UINT32 CC_ERROR: 1; //
UINT32 CARD_ECC_FAILED: 1; //
UINT32 ILLEGAL_COMMAND: 1; //
UINT32 COM_CRC_ERROR: 1; //
UINT32 LOCK_UNLOCK_FAILED: 1; //
UINT32 CARD_IS_LOCKED: 1; //
UINT32 WP_VIOLATION: 1; //
UINT32 ERASE_PARAM: 1; //
UINT32 ERASE_SEQ_ERROR: 1; //
UINT32 BLOCK_LEN_ERROR: 1; //
UINT32 ADDRESS_MISALIGN: 1; //
UINT32 ADDRESS_OUT_OF_RANGE:1; //
}CARD_STATUS;
typedef struct {
UINT32 CmdSet: 3;
UINT32 Reserved0: 5;
UINT32 Value: 8;
UINT32 Index: 8;
UINT32 Access: 2;
UINT32 Reserved1: 6;
}SWITCH_ARGUMENT;
#define CommandSet_Mode 0
#define SetBits_Mode 1
#define ClearBits_Mode 2
#define WriteByte_Mode 3
#define Idle_STATE 0
#define Ready_STATE 1
#define Ident_STATE 2
#define Stby_STATE 3
#define Tran_STATE 4
#define Data_STATE 5
#define Rcv_STATE 6
#define Prg_STATE 7
#define Dis_STATE 8
#define Btst_STATE 9
#pragma pack()
#endif

View File

@@ -0,0 +1,152 @@
/** @file
Header file for Industry SD Card 2.0 spec.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _SD_CARD_H
#define _SD_CARD_H
#include "MMC.h"
#pragma pack(1)
#define CHECK_PATTERN 0xAA ///< Physical Layer Simplified Specification Version 3.01 recommended 0xAA
#define ACMD6 6
#define ACMD13 13
#define ACMD23 23
#define ACMD41 41
#define ACMD42 42
#define ACMD51 51
#define SWITCH_FUNC CMD6
#define SEND_IF_COND CMD8
#define SET_BUS_WIDTH ACMD6
#define SD_STATUS ACMD13
#define SET_WR_BLK_ERASE_COUNT ACMD23
#define SD_SEND_OP_COND ACMD41
#define SET_CLR_CARD_DETECT ACMD42
#define SEND_SCR ACMD51
#define SD_BUS_WIDTH_1 0
#define SD_BUS_WIDTH_4 2
#define FREQUENCY_SD_PP (25 * 1000 * 1000)
#define FREQUENCY_SD_PP_HIGH (50 * 1000 * 1000)
#define SD_SPEC_10 0
#define SD_SPEC_11 1
#define SD_SPEC_20 2
#define VOLTAGE_27_36 0x1
typedef struct {
UINT8 NotUsed: 1; // 1 [0:0]
UINT8 CRC: 7; // CRC [7:1]
UINT8 ECC: 2; // ECC code [9:8]
UINT8 FILE_FORMAT: 2; // File format [11:10]
UINT8 TMP_WRITE_PROTECT: 1; // Temporary write protection [12:12]
UINT8 PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
UINT8 COPY: 1; // Copy flag (OTP) [14:14]
UINT8 FILE_FORMAT_GRP: 1; // File format group [15:15]
UINT16 Reserved0: 5; // 0 [20:16]
UINT16 WRITE_BL_PARTIAL: 1; // Partial blocks for write allowed [21:21]
UINT16 WRITE_BL_LEN: 4; // Max. write data block length [25:22]
UINT16 R2W_FACTOR: 3; // Write speed factor [28:26]
UINT16 DEFAULT_ECC: 2; // Manufacturer default ECC [30:29]
UINT16 WP_GRP_ENABLE: 1; // Write protect group enable [31:31]
UINT16 WP_GRP_SIZE: 7; // Write protect group size [38:32]
UINT16 SECTOR_SIZE: 7; // Erase sector size [45:39]
UINT16 ERASE_BLK_EN: 1; // Erase single block enable [46:46]
UINT16 Reserved1: 1; // 0 [47:47]
UINT32 C_SIZE: 22; // Device size [69:48]
UINT32 Reserved2: 6; // 0 [75:70]
UINT32 DSR_IMP: 1; // DSR implemented [76:76]
UINT32 READ_BLK_MISALIGN: 1; // Read block misalignment [77:77]
UINT32 WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
UINT32 READ_BL_PARTIAL: 1; // Partial blocks for read allowed [79:79]
UINT16 READ_BL_LEN: 4; // Max. read data block length [83:80]
UINT16 CCC: 12; // Card command classes [95:84]
UINT8 TRAN_SPEED ; // Max. bus clock frequency [103:96]
UINT8 NSAC ; // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
UINT8 TAAC ; // Data read access-time 1 [119:112]
UINT8 Reserved3: 6; // 0 [125:120]
UINT8 CSD_STRUCTURE: 2; // CSD structure [127:126]
}CSD_SDV2;
typedef struct {
UINT32 Reserved0;
UINT32 Reserved1: 16;
UINT32 SD_BUS_WIDTH: 4;
UINT32 SD_SECURITY: 3;
UINT32 DATA_STAT_AFTER_ERASE: 1;
UINT32 SD_SPEC: 4;
UINT32 SCR_STRUCT: 4;
}SCR;
typedef struct {
UINT8 Reserved0[50];
UINT8 ERASE_OFFSET: 2;
UINT8 ERASE_TIMEOUT: 6;
UINT16 ERASE_SIZE;
UINT8 Reserved1: 4;
UINT8 AU_SIZE: 4;
UINT8 PERFORMANCE_MOVE;
UINT8 SPEED_CLASS;
UINT32 SIZE_OF_PROTECTED_AREA;
UINT32 SD_CARD_TYPE: 16;
UINT32 Reserved2: 13;
UINT32 SECURED_MODE: 1;
UINT32 DAT_BUS_WIDTH: 2;
}SD_STATUS_REG;
typedef struct {
UINT8 Reserved0[34];
UINT16 Group1BusyStatus;
UINT16 Group2BusyStatus;
UINT16 Group3BusyStatus;
UINT16 Group4BusyStatus;
UINT16 Group5BusyStatus;
UINT16 Group6BusyStatus;
UINT8 DataStructureVersion;
UINT8 Group21Status;
UINT8 Group43Status;
UINT8 Group65Status;
UINT16 Group1Function;
UINT16 Group2Function;
UINT16 Group3Function;
UINT16 Group4Function;
UINT16 Group5Function;
UINT16 Group6Function;
UINT16 MaxCurrent;
}SWITCH_STATUS;
#pragma pack()
#endif

View File

@@ -0,0 +1,339 @@
/** @file
Interface definition for EFI_SD_HOST_IO_PROTOCOL.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _SD_HOST_IO_H
#define _SD_HOST_IO_H
#include "SDCard.h"
#include "CEATA.h"
#define EFI_SD_HOST_IO_PROTOCOL_GUID \
{ \
0xb63f8ec7, 0xa9c9, 0x4472, {0xa4, 0xc0, 0x4d, 0x8b, 0xf3, 0x65, 0xcc, 0x51} \
}
///
/// Forward reference for pure ANSI compatability
///
typedef struct _EFI_SD_HOST_IO_PROTOCOL EFI_SD_HOST_IO_PROTOCOL;
typedef enum {
ResponseNo = 0,
ResponseR1,
ResponseR1b,
ResponseR2,
ResponseR3,
ResponseR4,
ResponseR5,
ResponseR5b,
ResponseR6,
ResponseR7
}RESPONSE_TYPE;
typedef enum {
NoData = 0,
InData,
OutData
}TRANSFER_TYPE;
typedef enum {
Reset_Auto = 0,
Reset_DAT,
Reset_CMD,
Reset_DAT_CMD,
Reset_All
}RESET_TYPE;
#define PCI_SUBCLASS_SD_HOST_CONTROLLER 0x05
#define PCI_IF_STANDARD_HOST_NO_DMA 0x00
#define PCI_IF_STANDARD_HOST_SUPPORT_DMA 0x01
#define SDHCI_SPEC_100 0
#define SDHCI_SPEC_200 1
#define SDHCI_SPEC_300 2
//
//MMIO Registers definition for MMC/SDIO controller
//
#define MMIO_DMAADR 0x00
#define MMIO_BLKSZ 0x04
#define MMIO_BLKCNT 0x06
#define MMIO_CMDARG 0x08
#define MMIO_XFRMODE 0x0C
#define MMIO_SDCMD 0x0E
#define MMIO_RESP 0x10
#define MMIO_BUFDATA 0x20
#define MMIO_PSTATE 0x24
#define MMIO_HOSTCTL 0x28
#define MMIO_PWRCTL 0x29
#define MMIO_BLKGAPCTL 0x2A
#define MMIO_WAKECTL 0x2B
#define MMIO_CLKCTL 0x2C
#define V_MMIO_CLKCTL_MAX_8BIT_FREQ_SEL 0x80
#define V_MMIO_CLKCTL_MAX_10BIT_FREQ_SEL 0x3FF
#define B_MMIO_CLKCTL_UPR_SDCLK_FREQ_SEL_MASK 0xC0
#define MMIO_TOCTL 0x2E
#define MMIO_SWRST 0x2F
#define MMIO_NINTSTS 0x30
#define MMIO_ERINTSTS 0x32
#define MMIO_NINTEN 0x34
#define MMIO_ERINTEN 0x36
#define MMIO_NINTSIGEN 0x38
#define MMIO_ERINTSIGEN 0x3A
#define MMIO_AC12ERRSTS 0x3C
#define MMIO_HOSTCTL2 0x3E
#define MMIO_CAP 0x40
#define MMIO_MCCAP 0x48
#define MMIO_SLTINTSTS 0xFC
#define MMIO_CTRLRVER 0xFE
#define MMIO_SRST 0x1FC
//
// Protocol definitions
//
/**
The main function used to send the command to the card inserted into the SD host slot.
It will assemble the arguments to set the command register and wait for the command
and transfer completed until timeout. Then it will read the response register to fill
the ResponseData.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param CommandIndex The command index to set the command index field of command register.
@param Argument Command argument to set the argument field of command register.
@param DataType TRANSFER_TYPE, indicates no data, data in or data out.
@param Buffer Contains the data read from / write to the device.
@param BufferSize The size of the buffer.
@param ResponseType RESPONSE_TYPE.
@param TimeOut Time out value in 1 ms unit.
@param ResponseData Depending on the ResponseType, such as CSD or card status.
@retval EFI_SUCCESS
@retval EFI_INVALID_PARAMETER
@retval EFI_OUT_OF_RESOURCES
@retval EFI_TIMEOUT
@retval EFI_DEVICE_ERROR
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SEND_COMMAND) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT16 CommandIndex,
IN UINT32 Argument,
IN TRANSFER_TYPE DataType,
IN UINT8 *Buffer, OPTIONAL
IN UINT32 BufferSize,
IN RESPONSE_TYPE ResponseType,
IN UINT32 TimeOut,
OUT UINT32 *ResponseData OPTIONAL
);
/**
Set max clock frequency of the host, the actual frequency may not be the same as MaxFrequency.
It depends on the max frequency the host can support, divider, and host speed mode.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param MaxFrequency Max frequency in HZ.
@retval EFI_SUCCESS
@retval EFI_TIMEOUT
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_CLOCK_FREQUENCY) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT32 MaxFrequency
);
/**
Set bus width of the host controller
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param BusWidth Bus width in 1, 4, 8 bits.
@retval EFI_SUCCESS
@retval EFI_INVALID_PARAMETER
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_BUS_WIDTH) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT32 BusWidth
);
/**
Set voltage which could supported by the host controller.
Support 0(Power off the host), 1.8V, 3.0V, 3.3V
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param Voltage Units in 0.1 V.
@retval EFI_SUCCESS
@retval EFI_INVALID_PARAMETER
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_HOST_VOLTAGE) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT32 Voltage
);
/**
Reset the host controller.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param ResetAll TRUE to reset all.
@retval EFI_SUCCESS
@retval EFI_TIMEOUT
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_RESET_SD_HOST) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN RESET_TYPE ResetType
);
/**
Enable auto stop on the host controller.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param Enable TRUE to enable, FALSE to disable.
@retval EFI_SUCCESS
@retval EFI_TIMEOUT
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_ENABLE_AUTO_STOP_CMD) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN BOOLEAN Enable
);
/**
Find whether these is a card inserted into the slot. If so init the host.
If not, return EFI_NOT_FOUND.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@retval EFI_SUCCESS
@retval EFI_NOT_FOUND
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_DETECT_CARD_AND_INIT_HOST) (
IN EFI_SD_HOST_IO_PROTOCOL *This
);
/**
Set the Block length on the host controller.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param BlockLength card supportes block length.
@retval EFI_SUCCESS
@retval EFI_TIMEOUT
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_SET_BLOCK_LENGTH) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT32 BlockLength
);
/**
Enable/Disable High Speed transfer mode
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param Enable TRUE to Enable, FALSE to Disable
@return EFI_SUCCESS
**/
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_HIGH_SPEED_MODE) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN BOOLEAN Enable
);
typedef
EFI_STATUS
(EFIAPI *EFI_SD_HOST_IO_PROTOCOL_DUAL_DATARATE_MODE) (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN BOOLEAN Enable
);
#define EFI_SD_HOST_IO_PROTOCOL_REVISION_01 0x02
typedef struct {
UINT32 HighSpeedSupport: 1; //High speed supported
UINT32 V18Support: 1; //1.8V supported
UINT32 V30Support: 1; //3.0V supported
UINT32 V33Support: 1; //3.3V supported
UINT32 Reserved0: 4;
UINT32 HostVersion: 8;
UINT32 BusWidth4: 1; // 4 bit width
UINT32 BusWidth8: 1; // 8 bit width
UINT32 Reserved1: 14;
UINT32 BoundarySize;
}HOST_CAPABILITY;
//
// Interface structure for the SD HOST I/O Protocol
//
struct _EFI_SD_HOST_IO_PROTOCOL {
UINT32 Revision;
HOST_CAPABILITY HostCapability;
EFI_SD_HOST_IO_PROTOCOL_SEND_COMMAND SendCommand;
EFI_SD_HOST_IO_PROTOCOL_SET_CLOCK_FREQUENCY SetClockFrequency;
EFI_SD_HOST_IO_PROTOCOL_SET_BUS_WIDTH SetBusWidth;
EFI_SD_HOST_IO_PROTOCOL_SET_HOST_VOLTAGE SetHostVoltage;
EFI_SD_HOST_IO_PROTOCOL_RESET_SD_HOST ResetSDHost;
EFI_SD_HOST_IO_PROTOCOL_ENABLE_AUTO_STOP_CMD EnableAutoStopCmd;
EFI_SD_HOST_IO_PROTOCOL_DETECT_CARD_AND_INIT_HOST DetectCardAndInitHost;
EFI_SD_HOST_IO_PROTOCOL_SET_BLOCK_LENGTH SetBlockLength;
EFI_SD_HOST_IO_PROTOCOL_HIGH_SPEED_MODE SetHighSpeedMode;
EFI_SD_HOST_IO_PROTOCOL_DUAL_DATARATE_MODE SetDDRMode;
};
extern EFI_GUID gEfiSDHostIoProtocolGuid;
#endif

View File

@@ -0,0 +1,61 @@
/** @file
Common header file shared by all source files.
This file includes package header files, library classes and protocol, PPI & GUID definitions.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __COMMON_HEADER_H_
#define __COMMON_HEADER_H_
//
// The package level header files this module uses
//
#include <PiDxe.h>
#include <Ioh.h>
#include <IohCommonDefinitions.h>
//
// The protocols, PPI and GUID defintions for this module
//
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/PciIo.h>
#include <Protocol/DevicePath.h>
//
// The Library classes this module consumes
//
#include <Library/BaseLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
#include <Library/S3PciLib.h>
#include <Library/S3IoLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PciLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/S3BootScriptLib.h>
#include <Library/DevicePathLib.h>
#include <Library/TimerLib.h>
#include <Library/IoLib.h>
#include <Library/DevicePathLib.h>
#include <Library/IohLib.h>
#include <Library/MemoryAllocationLib.h>
#include <IndustryStandard/Pci.h>
#endif

View File

@@ -0,0 +1,89 @@
/** @file
Head file for BDS Platform specific code
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _IOH_BDS_H
#define _IOH_BDS_H
#include <Ioh.h>
#include <Protocol/DevicePath.h>
#include <Library/DevicePathLib.h>
extern EFI_DEVICE_PATH_PROTOCOL *gDeviceConnectOption [];
#define PCI_DEVICE_PATH_NODE(Func, Dev) \
{ \
{ \
HARDWARE_DEVICE_PATH, \
HW_PCI_DP, \
{ \
(UINT8) (sizeof (PCI_DEVICE_PATH)), \
(UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
} \
}, \
(Func), \
(Dev) \
}
#define PNPID_DEVICE_PATH_NODE(PnpId) \
{ \
{ \
ACPI_DEVICE_PATH, \
ACPI_DP, \
{ \
(UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
(UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
} \
}, \
EISA_PNP_ID((PnpId)), \
0 \
}
#define gEndEntire \
{ \
END_DEVICE_PATH_TYPE, \
END_ENTIRE_DEVICE_PATH_SUBTYPE, \
{ \
END_DEVICE_PATH_LENGTH, \
0 \
} \
}
#define gPciRootBridge \
PNPID_DEVICE_PATH_NODE(0x0A03)
//
// Platform Root Bridge
//
typedef struct {
ACPI_HID_DEVICE_PATH PciRootBridge;
EFI_DEVICE_PATH_PROTOCOL End;
} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
typedef struct {
ACPI_HID_DEVICE_PATH PciRootBridge;
PCI_DEVICE_PATH IohDevice;
EFI_DEVICE_PATH_PROTOCOL End;
} IOH_PCI_USB_DEVICE_PATH;
//
// Ioh BDS Functions
//
#endif // _IOH_BDS_H

View File

@@ -0,0 +1,48 @@
/** @file
Defined the Ioh device path which will be used by
platform Bbd to perform the platform policy connect.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IohBds.h"
//
// Predefined platform root bridge
//
PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = {
gPciRootBridge,
gEndEntire
};
EFI_DEVICE_PATH_PROTOCOL* gPlatformRootBridges [] = {
(EFI_DEVICE_PATH_PROTOCOL*)&gPlatformRootBridge0,
NULL
};
//
// Ioh USB EHCI controller device path
//
IOH_PCI_USB_DEVICE_PATH gIohUsbDevicePath0 = {
gPciRootBridge,
PCI_DEVICE_PATH_NODE(IOH_EHCI_FUNCTION_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER),
gEndEntire
};
//
// Ioh predefined device connecting option
//
EFI_DEVICE_PATH_PROTOCOL* gDeviceConnectOption [] = {
// (EFI_DEVICE_PATH_PROTOCOL*)&gIohUsbDevicePath0,
NULL
};

View File

@@ -0,0 +1,43 @@
/** @file
QuarkSCSocId module initialization module
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "CommonHeader.h"
#include "IohBds.h"
/**
The entry function for IohInit driver.
This function just call initialization function.
@param ImageHandle The driver image handle for GmchInit driver
@param SystemTable The pointer to System Table
@retval EFI_SUCCESS Success to initialize every module.
@return EFI_STATUS The status of initialization work.
**/
EFI_STATUS
EFIAPI
IohInit (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
InitializeIohSsvidSsid(IOH_BUS, IOH_PCI_IOSF2AHB_0_DEV_NUM, 0);
InitializeIohSsvidSsid(IOH_BUS, IOH_PCI_IOSF2AHB_1_DEV_NUM, 0);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,82 @@
## @file
# Component description file for Quark South Cluster Init driver.
#
# IohInit driver implement QuarkSCSocId related drivers, includes:
# PciHostBridge, PciExpress, SmmAccess driver and LegacyRegion driver.
#
# This driver mainly do full initialization for the Soc chipet includes:
# 1. Initialize the PCI Express device.
# 2. Initialize the PciHostBridge, and allocate the I/O and memory space from GCD service.
# 3. Initialize the SmmAccess module and install EFI_SMM_ACCESS_PROTOCOL
# 4. Initialize the LegacyRegion module, install EFI_LEGACY_REGION_PROTOCOL and set below 1M
# memory attribute from MTRR.
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = IohInitDxe
FILE_GUID = 3FE2A8A3-C400-48F8-832F-7881A394C250
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = IohInit
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
IohInit.c
IohBds.h
IohData.c
CommonHeader.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
QuarkSocPkg/QuarkSocPkg.dec
[LibraryClasses]
S3BootScriptLib
PcdLib
HobLib
PciLib
BaseMemoryLib
MemoryAllocationLib
S3PciLib
UefiLib
DebugLib
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
DxeServicesTableLib
UefiDriverEntryPoint
BaseLib
S3IoLib
IoLib
DevicePathLib
IohLib
[Protocols]
gEfiPciRootBridgeIoProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiPciIoProtocolGuid
[Pcd]
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartBusNumber
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartDevNumber
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohUartFunctionNumber
[Depex]
TRUE

View File

@@ -0,0 +1,220 @@
/** @file
Provides definition of entry point to the common I2C module that produces
common I2C Controller functions used by I2C library services.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _I2CCOMMON_H_
#define _I2CCOMMON_H_
#include <Uefi.h>
#include <Base.h>
#include <Library/DebugLib.h>
#include <Library/TimerLib.h>
#include <Library/I2cLib.h>
#include <IohAccess.h>
#include <IohCommonDefinitions.h>
#include "I2cRegs.h"
//
// Constants that define I2C Controller timeout and max. polling time.
//
#define MAX_T_POLL_COUNT 100
#define TI2C_POLL 25 // microseconds
#define MAX_STOP_DET_POLL_COUNT ((1000 * 1000) / TI2C_POLL) // Extreme for expected Stop detect.
/**
The GetI2CIoPortBaseAddress() function gets IO port base address of I2C Controller.
Always reads PCI configuration space to get MMIO base address of I2C Controller.
@return The IO port base address of I2C controller.
**/
UINTN
GetI2CIoPortBaseAddress (
VOID
);
/**
The EnableI2CMmioSpace() function enables access to I2C MMIO space.
**/
VOID
EnableI2CMmioSpace (
VOID
);
/**
The DisableI2CController() functions disables I2C Controller.
**/
VOID
DisableI2CController (
VOID
);
/**
The EnableI2CController() function enables the I2C Controller.
**/
VOID
EnableI2CController (
VOID
);
/**
The WaitForStopDet() function waits until I2C STOP Condition occurs,
indicating transfer completion.
@retval EFI_SUCCESS Stop detected.
@retval EFI_TIMEOUT Timeout while waiting for stop condition.
@retval EFI_ABORTED Tx abort signaled in HW status register.
@retval EFI_DEVICE_ERROR Tx or Rx overflow detected.
**/
EFI_STATUS
WaitForStopDet (
VOID
);
/**
The InitializeInternal() function initialises internal I2C Controller
register values that are commonly required for I2C Write and Read transfers.
@param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
@retval EFI_SUCCESS I2C Operation completed successfully.
**/
EFI_STATUS
InitializeInternal (
IN EFI_I2C_ADDR_MODE AddrMode
);
/**
The WriteByte() function provides a standard way to execute a
standard single byte write to an IC2 device (without accessing
sub-addresses), as defined in the I2C Specification.
@param I2CAddress I2C Slave device address
@param Value The 8-bit value to write.
@retval EFI_SUCCESS Transfer success.
@retval EFI_UNSUPPORTED Unsupported input param.
@retval EFI_TIMEOUT Timeout while waiting xfer.
@retval EFI_ABORTED Controller aborted xfer.
@retval EFI_DEVICE_ERROR Device error detected by controller.
**/
EFI_STATUS
EFIAPI
WriteByte (
IN UINTN I2CAddress,
IN UINT8 Value
);
/**
The ReadByte() function provides a standard way to execute a
standard single byte read to an IC2 device (without accessing
sub-addresses), as defined in the I2C Specification.
@param I2CAddress I2C Slave device address
@param ReturnDataPtr Pointer to location to receive read byte.
@retval EFI_SUCCESS Transfer success.
@retval EFI_UNSUPPORTED Unsupported input param.
@retval EFI_TIMEOUT Timeout while waiting xfer.
@retval EFI_ABORTED Controller aborted xfer.
@retval EFI_DEVICE_ERROR Device error detected by controller.
**/
EFI_STATUS
EFIAPI
ReadByte (
IN UINTN I2CAddress,
OUT UINT8 *ReturnDataPtr
);
/**
The WriteMultipleByte() function provides a standard way to execute
multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
when writing block of data), as defined in the I2C Specification.
@param I2CAddress The I2C slave address of the device
with which to communicate.
@param WriteBuffer Contains the value of byte to be written to the
I2C slave device.
@param Length No. of bytes to be written.
@retval EFI_SUCCESS Transfer success.
@retval EFI_UNSUPPORTED Unsupported input param.
@retval EFI_TIMEOUT Timeout while waiting xfer.
@retval EFI_ABORTED Tx abort signaled in HW status register.
@retval EFI_DEVICE_ERROR Tx overflow detected.
**/
EFI_STATUS
EFIAPI
WriteMultipleByte (
IN UINTN I2CAddress,
IN UINT8 *WriteBuffer,
IN UINTN Length
);
/**
The ReadMultipleByte() function provides a standard way to execute
multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
when reading block of data), as defined in the I2C Specification (I2C combined
write/read protocol).
@param I2CAddress The I2C slave address of the device
with which to communicate.
@param Buffer Contains the value of byte data written or read from the
I2C slave device.
@param WriteLength No. of bytes to be written. In this case data
written typically contains sub-address or sub-addresses
in Hi-Lo format, that need to be read (I2C combined
write/read protocol).
@param ReadLength No. of bytes to be read from I2C slave device.
@retval EFI_SUCCESS Transfer success.
@retval EFI_UNSUPPORTED Unsupported input param.
@retval EFI_TIMEOUT Timeout while waiting xfer.
@retval EFI_ABORTED Tx abort signaled in HW status register.
@retval EFI_DEVICE_ERROR Rx underflow or Rx/Tx overflow detected.
**/
EFI_STATUS
EFIAPI
ReadMultipleByte (
IN UINTN I2CAddress,
IN OUT UINT8 *Buffer,
IN UINTN WriteLength,
IN UINTN ReadLength
);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
## @file
# Component description file for Quark South Cluster I2C library.
#
# I2C library implement QuarkSCSocId related drivers, includes:
# PciHostBridge, PciExpress, SmmAccess driver and LegacyRegion driver.
#
# This driver contains I2C bus access routines:
# 1. I2C Read (byte, multi-byte)
# 2. I2C Write (byte, multi-byte)
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = I2cLib
FILE_GUID = 462d127a-c143-469e-8449-b6e36beb04a8
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = I2cLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
CommonHeader.h
I2cLib.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
IntelFrameworkPkg/IntelFrameworkPkg.dec
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
QuarkSocPkg/QuarkSocPkg.dec
[LibraryClasses]
PcdLib
PciLib
BaseMemoryLib
MemoryAllocationLib
DebugLib
BaseLib
TimerLib
IoLib
IohLib
[FeaturePcd]
gEfiQuarkSCSocIdTokenSpaceGuid.PcdI2CFastModeEnabled
[FixedPcd]
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohI2cMmioBase
[Pcd]
[Depex]
TRUE

View File

@@ -0,0 +1,35 @@
/** @file
Common header file shared by all source files.
This file includes package header files, library classes and protocol, PPI & GUID definitions.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __COMMON_HEADER_H_
#define __COMMON_HEADER_H_
#include <PiPei.h>
#include <Ioh.h>
#include <IohCommonDefinitions.h>
#include <Library/IohLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CpuLib.h>
#include <Library/PciCf8Lib.h>
#include <Library/IoLib.h>
#include <Library/PciLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <IndustryStandard/Pci22.h>
#endif

View File

@@ -0,0 +1,105 @@
/** @file
Lib function for Pei Quark South Cluster.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "CommonHeader.h"
/**
Program SVID/SID the same as VID/DID*
**/
EFI_STATUS
EFIAPI
InitializeIohSsvidSsid (
IN UINT8 Bus,
IN UINT8 Device,
IN UINT8 Func
)
{
UINTN Index;
for (Index = 0; Index <= IOH_PCI_IOSF2AHB_0_MAX_FUNCS; Index++) {
if (((Device == IOH_PCI_IOSF2AHB_1_DEV_NUM) && (Index >= IOH_PCI_IOSF2AHB_1_MAX_FUNCS))) {
continue;
}
IohMmPci32(0, Bus, Device, Index, PCI_REG_SVID0) = IohMmPci32(0, Bus, Device, Index, PCI_REG_VID);
}
return EFI_SUCCESS;
}
/* Enable memory, io, and bus master for USB controller */
VOID
EFIAPI
EnableUsbMemIoBusMaster (
IN UINT8 UsbBusNumber
)
{
UINT16 CmdReg;
CmdReg = PciRead16 (PCI_LIB_ADDRESS (UsbBusNumber, IOH_USB_OHCI_DEVICE_NUMBER, IOH_OHCI_FUNCTION_NUMBER, PCI_REG_PCICMD));
CmdReg = (UINT16) (CmdReg | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
PciWrite16 (PCI_LIB_ADDRESS (UsbBusNumber, IOH_USB_OHCI_DEVICE_NUMBER, IOH_OHCI_FUNCTION_NUMBER, PCI_REG_PCICMD), CmdReg);
CmdReg = PciRead16 (PCI_LIB_ADDRESS (UsbBusNumber, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, PCI_REG_PCICMD));
CmdReg = (UINT16) (CmdReg | EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_IO_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
PciWrite16 (PCI_LIB_ADDRESS (UsbBusNumber, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, PCI_REG_PCICMD), CmdReg);
}
/**
Read south cluster GPIO input from Port A.
**/
UINT32
EFIAPI
ReadIohGpioValues (
VOID
)
{
UINT32 GipData;
UINT32 GipAddr;
UINT32 TempBarAddr;
UINT16 SaveCmdReg;
UINT32 SaveBarReg;
TempBarAddr = (UINT32) PcdGet64(PcdIohGpioMmioBase);
GipAddr = PCI_LIB_ADDRESS(
PcdGet8 (PcdIohGpioBusNumber),
PcdGet8 (PcdIohGpioDevNumber),
PcdGet8 (PcdIohGpioFunctionNumber), 0);
//
// Save current settings for PCI CMD/BAR registers.
//
SaveCmdReg = PciRead16 (GipAddr + PCI_COMMAND_OFFSET);
SaveBarReg = PciRead32 (GipAddr + PcdGet8 (PcdIohGpioBarRegister));
DEBUG ((EFI_D_INFO, "SC GPIO temporary enable at %08X\n", TempBarAddr));
// Use predefined tempory memory resource.
PciWrite32 ( GipAddr + PcdGet8 (PcdIohGpioBarRegister), TempBarAddr);
PciWrite8 ( GipAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
// Read GPIO configuration
GipData = MmioRead32(TempBarAddr + GPIO_EXT_PORTA);
//
// Restore settings for PCI CMD/BAR registers.
//
PciWrite32 ((GipAddr + PcdGet8 (PcdIohGpioBarRegister)), SaveBarReg);
PciWrite16 (GipAddr + PCI_COMMAND_OFFSET, SaveCmdReg);
// Only 8 bits valid.
return GipData & 0x000000FF;
}

View File

@@ -0,0 +1,55 @@
## @file
# Intel Soc Library Instance
#
# Intel Soc Library Instance
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = IohLib
FILE_GUID = B4C12297-7B19-4523-B165-81374D96716B
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = IohLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
IohLib.c
CommonHeader.h
[Packages]
MdePkg/MdePkg.dec
QuarkSocPkg/QuarkSocPkg.dec
[LibraryClasses]
DebugLib
PciLib
IoLib
PciCf8Lib
BaseLib
CpuLib
[Pcd]
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBusNumber
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBusNumber
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioDevNumber
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioFunctionNumber
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioBarRegister
gEfiQuarkSCSocIdTokenSpaceGuid.PcdIohGpioMmioBase

View File

@@ -0,0 +1,233 @@
/** @file
UEFI Component Name(2) protocol implementation for SD controller driver.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "SDController.h"
//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gSDControllerName = {
SDControllerGetDriverName,
SDControllerGetControllerName,
"eng"
};
//
// EFI Component Name 2 Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gSDControllerName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SDControllerGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) SDControllerGetControllerName,
"en"
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSDControllerDriverNameTable[] = {
{ "eng;en", L"EFI SD Host Controller Driver" },
{ NULL, NULL }
};
//
// EFI Component Name Functions
//
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 3066 or ISO 639-2 language code format.
@param DriverName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
SDControllerGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
mSDControllerDriverNameTable,
DriverName,
(BOOLEAN)(This == &gSDControllerName)
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle[in] The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param ChildHandle[in] The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 3066 or ISO 639-2 language code format.
@param ControllerName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
SDControllerGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
EFI_STATUS Status;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
SDHOST_DATA *SDHostData;
//
// This is a device driver, so ChildHandle must be NULL.
//
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver is currently managing ControllerHandle
//
Status = EfiTestManagedDevice (
ControllerHandle,
gSDControllerDriverBinding.DriverBindingHandle,
&gEfiPciIoProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the device context
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSDHostIoProtocolGuid,
(VOID **) &SDHostIo,
gSDControllerDriverBinding.DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
SDHostData = SDHOST_DATA_FROM_THIS(SDHostIo);
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
SDHostData->ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gSDControllerName)
);
}

View File

@@ -0,0 +1,147 @@
/** @file
This file contains the delarations for componet name routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _COMPONENT_NAME_H_
#define _COMPONENT_NAME_H_
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 3066 or ISO 639-2 language code format.
@param DriverName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
SDControllerGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle[in] The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param ChildHandle[in] The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 3066 or ISO 639-2 language code format.
@param ControllerName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
SDControllerGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,322 @@
/** @file
The definition for SD host controller driver model and HC protocol routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _SD_CONTROLLER_H_
#define _SD_CONTROLLER_H_
#include <Uefi.h>
#include <Protocol/PciIo.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <IndustryStandard/Pci22.h>
#include "ComponentName.h"
#include "SDHostIo.h"
extern EFI_DRIVER_BINDING_PROTOCOL gSDControllerDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gSDControllerName;
extern EFI_COMPONENT_NAME2_PROTOCOL gSDControllerName2;
#define SDHOST_DATA_SIGNATURE SIGNATURE_32 ('s', 'd', 'h', 's')
#define BLOCK_SIZE 0x200
#define TIME_OUT_1S 1000
#pragma pack(1)
//
// PCI Class Code structure
//
typedef struct {
UINT8 PI;
UINT8 SubClassCode;
UINT8 BaseCode;
} PCI_CLASSC;
#pragma pack()
typedef struct {
UINTN Signature;
EFI_SD_HOST_IO_PROTOCOL SDHostIo;
EFI_PCI_IO_PROTOCOL *PciIo;
BOOLEAN IsAutoStopCmd;
UINT32 BaseClockInMHz;
UINT32 CurrentClockInKHz;
UINT32 BlockLength;
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
}SDHOST_DATA;
#define SDHOST_DATA_FROM_THIS(a) \
CR(a, SDHOST_DATA, SDHostIo, SDHOST_DATA_SIGNATURE)
/**
Test to see if this driver supports ControllerHandle. Any
ControllerHandle that has SDHostIoProtocol installed will be supported.
@param This Protocol instance pointer.
@param Controller Handle of device to test.
@param RemainingDevicePath Not used.
@return EFI_SUCCESS This driver supports this device.
@return EFI_UNSUPPORTED This driver does not support this device.
**/
EFI_STATUS
EFIAPI
SDControllerSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Starting the SD Host Controller Driver.
@param This Protocol instance pointer.
@param Controller Handle of device to test.
@param RemainingDevicePath Not used.
@retval EFI_SUCCESS This driver supports this device.
@retval EFI_UNSUPPORTED This driver does not support this device.
@retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
**/
EFI_STATUS
EFIAPI
SDControllerStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
@param This Protocol instance pointer.
@param Controller Handle of device to stop driver on.
@param NumberOfChildren Number of Children in the ChildHandleBuffer.
@param ChildHandleBuffer List of handles for the children we need to stop.
@return EFI_SUCCESS
@return others
**/
EFI_STATUS
EFIAPI
SDControllerStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
/**
The main function used to send the command to the card inserted into the SD host slot.
It will assemble the arguments to set the command register and wait for the command
and transfer completed until timeout. Then it will read the response register to fill
the ResponseData.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param CommandIndex The command index to set the command index field of command register.
@param Argument Command argument to set the argument field of command register.
@param DataType TRANSFER_TYPE, indicates no data, data in or data out.
@param Buffer Contains the data read from / write to the device.
@param BufferSize The size of the buffer.
@param ResponseType RESPONSE_TYPE.
@param TimeOut Time out value in 1 ms unit.
@param ResponseData Depending on the ResponseType, such as CSD or card status.
@retval EFI_SUCCESS
@retval EFI_INVALID_PARAMETER
@retval EFI_OUT_OF_RESOURCES
@retval EFI_TIMEOUT
@retval EFI_DEVICE_ERROR
**/
EFI_STATUS
EFIAPI
SendCommand (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT16 CommandIndex,
IN UINT32 Argument,
IN TRANSFER_TYPE DataType,
IN UINT8 *Buffer, OPTIONAL
IN UINT32 BufferSize,
IN RESPONSE_TYPE ResponseType,
IN UINT32 TimeOut,
OUT UINT32 *ResponseData OPTIONAL
);
/**
Set max clock frequency of the host, the actual frequency may not be the same as MaxFrequency.
It depends on the max frequency the host can support, divider, and host speed mode.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param MaxFrequency Max frequency in HZ.
@retval EFI_SUCCESS
@retval EFI_TIMEOUT
**/
EFI_STATUS
EFIAPI
SetClockFrequency (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT32 MaxFrequencyInKHz
);
/**
Set bus width of the host controller
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param BusWidth Bus width in 1, 4, 8 bits.
@retval EFI_SUCCESS
@retval EFI_INVALID_PARAMETER
**/
EFI_STATUS
EFIAPI
SetBusWidth (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT32 BusWidth
);
/**
Set voltage which could supported by the host controller.
Support 0(Power off the host), 1.8V, 3.0V, 3.3V
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param Voltage Units in 0.1 V.
@retval EFI_SUCCESS
@retval EFI_INVALID_PARAMETER
**/
EFI_STATUS
EFIAPI
SetHostVoltage (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT32 Voltage
);
/**
Reset the host controller.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param ResetAll TRUE to reset all.
@retval EFI_SUCCESS
@retval EFI_TIMEOUT
**/
EFI_STATUS
EFIAPI
ResetSDHost (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN RESET_TYPE ResetType
);
/**
Enable auto stop on the host controller.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param Enable TRUE to enable, FALSE to disable.
@retval EFI_SUCCESS
@retval EFI_TIMEOUT
**/
EFI_STATUS
EFIAPI
EnableAutoStopCmd (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN BOOLEAN Enable
);
/**
Find whether these is a card inserted into the slot. If so init the host.
If not, return EFI_NOT_FOUND.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@retval EFI_SUCCESS
@retval EFI_NOT_FOUND
**/
EFI_STATUS
EFIAPI
DetectCardAndInitHost (
IN EFI_SD_HOST_IO_PROTOCOL *This
);
/**
Set the Block length on the host controller.
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param BlockLength card supportes block length.
@retval EFI_SUCCESS
@retval EFI_TIMEOUT
**/
EFI_STATUS
EFIAPI
SetBlockLength (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN UINT32 BlockLength
);
/**
Enable/Disable High Speed transfer mode
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param Enable TRUE to Enable, FALSE to Disable
@return EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
SetHighSpeedMode (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN BOOLEAN Enable
);
EFI_STATUS
EFIAPI
SetDDRMode (
IN EFI_SD_HOST_IO_PROTOCOL *This,
IN BOOLEAN Enable
);
#endif

View File

@@ -0,0 +1,62 @@
## @file
#
# Component Description File For SDControllerDxe Module.
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SDController
FILE_GUID = 90A330BD-6F89-4900-933A-C25EB4356348
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializeSDController
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
# DRIVER_BINDING = gSDControllerDriverBinding
# COMPONENT_NAME = gSDControllerName
# COMPONENT_NAME2 = gSDControllerName2
#
[Sources]
SDController.c
SDController.h
ComponentName.c
ComponentName.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
QuarkSocPkg/QuarkSocPkg.dec
[LibraryClasses]
MemoryAllocationLib
BaseLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
BaseMemoryLib
DebugLib
PcdLib
[Protocols]
gEfiPciIoProtocolGuid ## TO_START
gEfiSDHostIoProtocolGuid ## BY_START
[FeaturePcd]
gEfiQuarkSCSocIdTokenSpaceGuid.PcdSdHciQuirkNoHiSpd

View File

@@ -0,0 +1,656 @@
/** @file
CEATA specific functions implementation
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "SDMediaDevice.h"
/**
Send RW_MULTIPLE_REGISTER command
@param CardData Pointer to CARD_DATA.
@param Address Register address.
@param ByteCount Buffer size.
@param Write TRUE means write, FALSE means read.
@param Buffer Buffer pointer.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
ReadWriteMultipleRegister (
IN CARD_DATA *CardData,
IN UINT16 Address,
IN UINT8 ByteCount,
IN BOOLEAN Write,
IN UINT8 *Buffer
)
{
EFI_STATUS Status;
UINT32 Argument;
Status = EFI_SUCCESS;
if ((Address % 4 != 0) || (ByteCount % 4 != 0)) {
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
Argument = (Address << 16) | ByteCount;
if (Write) {
Argument |= BIT31;
}
if (Write) {
CopyMem (CardData->AlignedBuffer, Buffer, ByteCount);
Status = SendCommand (
CardData,
RW_MULTIPLE_REGISTER,
Argument,
OutData,
CardData->AlignedBuffer,
ByteCount,
ResponseR1b,
TIMEOUT_DATA,
(UINT32*)&(CardData->CardStatus)
);
} else {
Status = SendCommand (
CardData,
RW_MULTIPLE_REGISTER,
Argument,
InData,
CardData->AlignedBuffer,
ByteCount,
ResponseR1,
TIMEOUT_DATA,
(UINT32*)&(CardData->CardStatus)
);
if (!EFI_ERROR (Status)) {
CopyMem (Buffer, CardData->AlignedBuffer, ByteCount);
}
}
Exit:
return Status;
}
/**
Send ReadWriteMultipleBlock command with RW_MULTIPLE_REGISTER command
@param CardData Pointer to CARD_DATA.
@param DataUnitCount Buffer size in 512 bytes unit.
@param Write TRUE means write, FALSE means read.
@param Buffer Buffer pointer.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
ReadWriteMultipleBlock (
IN CARD_DATA *CardData,
IN UINT16 DataUnitCount,
IN BOOLEAN Write,
IN UINT8 *Buffer
)
{
EFI_STATUS Status;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
UINT32 TransferLength;
Status = EFI_SUCCESS;
SDHostIo = CardData->SDHostIo;
TransferLength = DataUnitCount * DATA_UNIT_SIZE;
if (TransferLength > SDHostIo->HostCapability.BoundarySize) {
return EFI_INVALID_PARAMETER;
}
if (Write) {
CopyMem (CardData->AlignedBuffer, Buffer, TransferLength);
Status = SendCommand (
CardData,
RW_MULTIPLE_BLOCK,
(DataUnitCount | BIT31),
OutData,
CardData->AlignedBuffer,
TransferLength,
ResponseR1b,
TIMEOUT_DATA,
(UINT32*)&(CardData->CardStatus)
);
} else {
Status = SendCommand (
CardData,
RW_MULTIPLE_BLOCK,
DataUnitCount,
InData,
CardData->AlignedBuffer,
TransferLength,
ResponseR1,
TIMEOUT_DATA,
(UINT32*)&(CardData->CardStatus)
);
if (!EFI_ERROR (Status)) {
CopyMem (Buffer, CardData->AlignedBuffer, TransferLength);
}
}
return Status;
}
/**
Send software reset
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
SoftwareReset (
IN CARD_DATA *CardData
)
{
EFI_STATUS Status;
UINT8 Data;
UINT32 TimeOut;
Data = BIT2;
Status = FastIO (CardData, Reg_Control, &Data, TRUE);
if (EFI_ERROR (Status)) {
goto Exit;
}
TimeOut = 5 * 1000;
do {
gBS->Stall (1 * 1000);
Status = FastIO (CardData, Reg_Control, &Data, FALSE);
if (EFI_ERROR (Status)) {
goto Exit;
}
if ((Data & BIT2) == BIT2) {
break;
}
TimeOut--;
} while (TimeOut > 0);
if (TimeOut == 0) {
Status = EFI_TIMEOUT;
goto Exit;
}
Data &= ~BIT2;
Status = FastIO (CardData, Reg_Control, &Data, TRUE);
TimeOut = 5 * 1000;
do {
gBS->Stall (1 * 1000);
Status = FastIO (CardData, Reg_Control, &Data, FALSE);
if (EFI_ERROR (Status)) {
goto Exit;
}
if ((Data & BIT2) != BIT2) {
break;
}
TimeOut--;
} while (TimeOut > 0);
if (TimeOut == 0) {
Status = EFI_TIMEOUT;
goto Exit;
}
Exit:
return Status;
}
/**
SendATACommand specificed in Taskfile
@param CardData Pointer to CARD_DATA.
@param TaskFile Pointer to TASK_FILE.
@param Write TRUE means write, FALSE means read.
@param Buffer If NULL, means no data transfer, neither read nor write.
@param SectorCount Buffer size in 512 bytes unit.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
SendATACommand (
IN CARD_DATA *CardData,
IN TASK_FILE *TaskFile,
IN BOOLEAN Write,
IN UINT8 *Buffer,
IN UINT16 SectorCount
)
{
EFI_STATUS Status;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
UINT8 Data;
UINT32 TimeOut;
SDHostIo = CardData->SDHostIo;
//
//Write register
//
Status = ReadWriteMultipleRegister (
CardData,
0,
sizeof (TASK_FILE),
TRUE,
(UINT8*)TaskFile
);
if (EFI_ERROR (Status)) {
DEBUG((EFI_D_ERROR, "ReadWriteMultipleRegister 0x%x\n", Status));
goto Exit;
}
TimeOut = 5000;
do {
gBS->Stall (1 * 1000);
Data = 0;
Status = FastIO (
CardData,
Reg_Command_Status,
&Data,
FALSE
);
if (EFI_ERROR (Status)) {
return Status;
}
if (((Data & BIT7) == 0) && ((Data & BIT6) == BIT6)) {
break;
}
TimeOut --;
} while (TimeOut > 0);
if (TimeOut == 0) {
DEBUG((EFI_D_ERROR, "ReadWriteMultipleRegister FastIO EFI_TIMEOUT 0x%x\n", Data));
Status = EFI_TIMEOUT;
goto Exit;
}
if (Buffer != NULL) {
Status = ReadWriteMultipleBlock (
CardData,
SectorCount,
Write,
(UINT8*)Buffer
);
if (EFI_ERROR (Status)) {
DEBUG((EFI_D_ERROR, "ReadWriteMultipleBlock EFI_TIMEOUT 0x%x\n", Status));
goto Exit;
}
TimeOut = 5 * 1000;
do {
gBS->Stall (1 * 1000);
Data = 0;
Status = FastIO (
CardData,
Reg_Command_Status,
&Data,
FALSE
);
if (EFI_ERROR (Status)) {
return Status;
}
if (((Data & BIT7) == 0) && ((Data & BIT3) == 0)) {
break;
}
TimeOut --;
} while (TimeOut > 0);
if (TimeOut == 0) {
DEBUG((EFI_D_ERROR, "ReadWriteMultipleBlock FastIO EFI_TIMEOUT 0x%x\n", Data));
Status = EFI_TIMEOUT;
goto Exit;
}
if (((Data & BIT6) == BIT6) && (Data & BIT0) == 0) {
Status = EFI_SUCCESS;
} else {
Status = EFI_DEVICE_ERROR;
}
}
Exit:
if (EFI_ERROR (Status)) {
SoftwareReset (CardData);
}
return Status;
}
/**
IDENTIFY_DEVICE command
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
IndentifyDevice (
IN CARD_DATA *CardData
)
{
EFI_STATUS Status;
ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
//
//The host only supports nIEN = 0
//
CardData->TaskFile.Command_Status = IDENTIFY_DEVICE;
Status = SendATACommand (
CardData,
&CardData->TaskFile,
FALSE,
(UINT8*)&(CardData->IndentifyDeviceData),
1
);
return Status;
}
/**
FLUSH_CACHE_EXT command
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
FlushCache (
IN CARD_DATA *CardData
)
{
//
//Hitachi CE-ATA will always make the busy high after
//receving this command
//
/*
EFI_STATUS Status;
ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
//
//The host only supports nIEN = 0
//
CardData->TaskFile.Command_Status = FLUSH_CACHE_EXT;
Status = SendATACommand (
CardData,
&CardData->TaskFile,
FALSE,
NULL,
0
);
*/
return EFI_SUCCESS;
}
/**
STANDBY_IMMEDIATE command
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
StandByImmediate (
IN CARD_DATA *CardData
)
{
EFI_STATUS Status;
ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
//
//The host only supports nIEN = 0
//
CardData->TaskFile.Command_Status = STANDBY_IMMEDIATE;
Status = SendATACommand (
CardData,
&CardData->TaskFile,
FALSE,
NULL,
0
);
return Status;
}
/**
READ_DMA_EXT command
@param CardData Pointer to CARD_DATA.
@param LBA The starting logical block address to read from on the device.
@param Buffer A pointer to the destination buffer for the data. The caller
is responsible for either having implicit or explicit ownership
of the buffer.
@param SectorCount Size in 512 bytes unit.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
ReadDMAExt (
IN CARD_DATA *CardData,
IN EFI_LBA LBA,
IN UINT8 *Buffer,
IN UINT16 SectorCount
)
{
EFI_STATUS Status;
ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
//
//The host only supports nIEN = 0
//
CardData->TaskFile.Command_Status = READ_DMA_EXT;
CardData->TaskFile.SectorCount = (UINT8)SectorCount;
CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);
CardData->TaskFile.LBALow = (UINT8)LBA;
CardData->TaskFile.LBAMid = (UINT8)RShiftU64(LBA, 8);
CardData->TaskFile.LBAHigh = (UINT8)RShiftU64(LBA, 16);
CardData->TaskFile.LBALow_Exp = (UINT8)RShiftU64(LBA, 24);
CardData->TaskFile.LBAMid_Exp = (UINT8)RShiftU64(LBA, 32);
CardData->TaskFile.LBAHigh_Exp = (UINT8)RShiftU64(LBA, 40);
Status = SendATACommand (
CardData,
&CardData->TaskFile,
FALSE,
Buffer,
SectorCount
);
return Status;
}
/**
WRITE_DMA_EXT command
@param CardData Pointer to CARD_DATA.
@param LBA The starting logical block address to read from on the device.
@param Buffer A pointer to the destination buffer for the data. The caller
is responsible for either having implicit or explicit ownership
of the buffer.
@param SectorCount Size in 512 bytes unit.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
WriteDMAExt (
IN CARD_DATA *CardData,
IN EFI_LBA LBA,
IN UINT8 *Buffer,
IN UINT16 SectorCount
)
{
EFI_STATUS Status;
ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
//
//The host only supports nIEN = 0
//
CardData->TaskFile.Command_Status = WRITE_DMA_EXT;
CardData->TaskFile.SectorCount = (UINT8)SectorCount;
CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);
CardData->TaskFile.LBALow = (UINT8)LBA;
CardData->TaskFile.LBAMid = (UINT8)RShiftU64(LBA, 8);
CardData->TaskFile.LBAHigh = (UINT8)RShiftU64(LBA, 16);
CardData->TaskFile.LBALow_Exp = (UINT8)RShiftU64(LBA, 24);
CardData->TaskFile.LBAMid_Exp = (UINT8)RShiftU64(LBA, 32);
CardData->TaskFile.LBAHigh_Exp = (UINT8)RShiftU64(LBA, 40);
Status = SendATACommand (
CardData,
&CardData->TaskFile,
TRUE,
Buffer,
SectorCount
);
return Status;
}
/**
Judge whether it is CE-ATA device or not.
@param CardData Pointer to CARD_DATA.
@retval TRUE
@retval FALSE
**/
BOOLEAN
IsCEATADevice (
IN CARD_DATA *CardData
)
{
EFI_STATUS Status;
Status = ReadWriteMultipleRegister (
CardData,
0,
sizeof (TASK_FILE),
FALSE,
(UINT8*)&CardData->TaskFile
);
if (EFI_ERROR (Status)) {
//
//To bring back the normal MMC card to work
//
CardData->SDHostIo->ResetSDHost (CardData->SDHostIo, Reset_DAT_CMD);
return FALSE;
}
if (CardData->TaskFile.LBAMid == CE_ATA_SIG_CE &&
CardData->TaskFile.LBAHigh == CE_ATA_SIG_AA
) {
//
//Disable Auto CMD for CE-ATA
//
CardData->SDHostIo->EnableAutoStopCmd (CardData->SDHostIo, FALSE);
return TRUE;
}
return FALSE;
}

View File

@@ -0,0 +1,396 @@
/** @file
Block I/O protocol for CE-ATA device
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "SDMediaDevice.h"
/**
Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.
@param This The EFI_BLOCK_IO_PROTOCOL instance.
@param ExtendedVerification Indicates that the driver may perform a more exhaustive.
verification operation of the device during reset.
(This parameter is ingored in this driver.)
@retval EFI_SUCCESS Success
**/
EFI_STATUS
EFIAPI
CEATABlockReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
EFI_STATUS Status;
CARD_DATA *CardData;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
CardData = CARD_DATA_FROM_THIS(This);
SDHostIo = CardData->SDHostIo;
if (!ExtendedVerification) {
Status = SoftwareReset (CardData);
} else {
Status = SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD);
if (EFI_ERROR (Status)) {
DEBUG((EFI_D_ERROR, "CEATABlockReset: Fail to ResetSDHost\n" ));
return Status;
}
Status = MMCSDCardInit (CardData);
}
return Status;
}
/**
Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.
@param This The EFI_BLOCK_IO_PROTOCOL instance.
@param MediaId The media id that the write request is for.
@param LBA The starting logical block address to read from on the device.
The caller is responsible for writing to only legitimate locations.
@param BufferSize The size of the Buffer in bytes. This must be a multiple of the
intrinsic block size of the device.
@param Buffer A pointer to the destination buffer for the data. The caller
is responsible for either having implicit or explicit ownership
of the buffer.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
EFIAPI
CEATABlockReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
EFI_STATUS Status;
CARD_DATA *CardData;
UINT32 TransferSize;
UINT8 *pBuf;
UINT32 Index;
UINT64 Address;
UINT32 Remainder;
UINT64 CEATALBA;
UINT32 BoundarySize;
Status = EFI_SUCCESS;
CardData = CARD_DATA_FROM_THIS(This);
pBuf = Buffer;
Index = 0;
Address = MultU64x32(LBA, CardData->BlockIoMedia.BlockSize);
BoundarySize = CardData->SDHostIo->HostCapability.BoundarySize;
if (!Buffer) {
Status = EFI_INVALID_PARAMETER;
DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Invalid parameter\n" ));
goto Exit;
}
if (MediaId != CardData->BlockIoMedia.MediaId) {
Status = EFI_MEDIA_CHANGED;
DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Media changed\n" ));
goto Exit;
}
if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {
Status = EFI_BAD_BUFFER_SIZE;
DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Bad buffer size\n" ));
goto Exit;
}
if (BufferSize == 0) {
Status = EFI_SUCCESS;
goto Exit;
}
if ((Address + BufferSize) > MultU64x32 (CardData->BlockIoMedia.LastBlock + 1, CardData->BlockIoMedia.BlockSize)) {
Status = EFI_INVALID_PARAMETER;
DEBUG((EFI_D_ERROR, "CEATABlockReadBlocks:Invalid parameter\n" ));
goto Exit;
}
do {
if (BufferSize < BoundarySize) {
TransferSize = (UINT32)BufferSize;
} else {
TransferSize = BoundarySize;
}
Address += Index * TransferSize;
CEATALBA = DivU64x32Remainder (Address, DATA_UNIT_SIZE, &Remainder);
ASSERT(Remainder == 0);
Status = ReadDMAExt (
CardData,
CEATALBA,
pBuf,
(UINT16)(TransferSize / DATA_UNIT_SIZE)
);
if (EFI_ERROR (Status)) {
DEBUG((EFI_D_ERROR, "Read Failed at 0x%x, Index %d, Size 0x%x\n", Address, Index, TransferSize));
This->Reset (This, TRUE);
goto Exit;
}
BufferSize -= TransferSize;
pBuf += TransferSize;
Index ++;
} while (BufferSize != 0);
Exit:
return Status;
}
/**
Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.
@param This The EFI_BLOCK_IO_PROTOCOL instance.
@param MediaId The media id that the write request is for.
@param LBA The starting logical block address to read from on the device.
The caller is responsible for writing to only legitimate locations.
@param BufferSize The size of the Buffer in bytes. This must be a multiple of the
intrinsic block size of the device.
@param Buffer A pointer to the destination buffer for the data. The caller
is responsible for either having implicit or explicit ownership
of the buffer.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
EFIAPI
CEATABlockWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
EFI_STATUS Status;
CARD_DATA *CardData;
UINT32 TransferSize;
UINT8 *pBuf;
UINT32 Index;
UINT64 Address;
UINT32 Remainder;
UINT64 CEATALBA;
UINT32 BoundarySize;
Status = EFI_SUCCESS;
CardData = CARD_DATA_FROM_THIS(This);
pBuf = Buffer;
Index = 0;
Address = MultU64x32(LBA, CardData->BlockIoMedia.BlockSize);
BoundarySize = CardData->SDHostIo->HostCapability.BoundarySize;
if (!Buffer) {
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
if (MediaId != CardData->BlockIoMedia.MediaId) {
Status = EFI_MEDIA_CHANGED;
goto Exit;
}
if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {
Status = EFI_BAD_BUFFER_SIZE;
goto Exit;
}
if (BufferSize == 0) {
Status = EFI_SUCCESS;
goto Exit;
}
if (CardData->BlockIoMedia.ReadOnly) {
Status = EFI_WRITE_PROTECTED;
goto Exit;
}
if ((Address + BufferSize) > MultU64x32 (CardData->BlockIoMedia.LastBlock + 1, CardData->BlockIoMedia.BlockSize)) {
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
CardData->NeedFlush = TRUE;
do {
if (BufferSize < BoundarySize) {
TransferSize = (UINT32)BufferSize;
} else {
TransferSize = BoundarySize;
}
Address += Index * TransferSize;
CEATALBA = DivU64x32Remainder (Address, DATA_UNIT_SIZE, &Remainder);
ASSERT(Remainder == 0);
Status = WriteDMAExt (
CardData,
CEATALBA,
pBuf,
(UINT16)(TransferSize / DATA_UNIT_SIZE)
);
if (EFI_ERROR (Status)) {
DEBUG((EFI_D_ERROR, "Write Failed at 0x%x, Index %d, Size 0x%x\n", Address, Index, TransferSize));
This->Reset (This, TRUE);
goto Exit;
}
BufferSize -= TransferSize;
pBuf += TransferSize;
Index ++;
} while (BufferSize != 0);
Exit:
return Status;
}
/**
Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.
(In this driver, this function just returns EFI_SUCCESS.)
@param This The EFI_BLOCK_IO_PROTOCOL instance.
@retval EFI_SUCCESS
@retval Others
**/
EFI_STATUS
EFIAPI
CEATABlockFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
)
{
EFI_STATUS Status;
CARD_DATA *CardData;
CardData = CARD_DATA_FROM_THIS(This);
if (CardData->NeedFlush) {
CardData->NeedFlush = FALSE;
Status = FlushCache (CardData);
}
return EFI_SUCCESS;
}
/**
CEATA card BlockIo init function.
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS
@retval Others
**/
EFI_STATUS
CEATABlockIoInit (
IN CARD_DATA *CardData
)
/*++
Routine Description:
CEATA card BlockIo init function
Arguments:
CardData - Pointer to CARD_DATA
Returns:
EFI_SUCCESS - Success
--*/
{
EFI_STATUS Status;
UINT64 MaxSize;
UINT32 Remainder;
//
//BlockIO protocol
//
CardData->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;
CardData->BlockIo.Media = &(CardData->BlockIoMedia);
CardData->BlockIo.Reset = CEATABlockReset;
CardData->BlockIo.ReadBlocks = CEATABlockReadBlocks ;
CardData->BlockIo.WriteBlocks = CEATABlockWriteBlocks;
CardData->BlockIo.FlushBlocks = CEATABlockFlushBlocks;
CardData->BlockIoMedia.MediaId = 0;
CardData->BlockIoMedia.RemovableMedia = FALSE;
CardData->BlockIoMedia.MediaPresent = TRUE;
CardData->BlockIoMedia.LogicalPartition = FALSE;
if (CardData->CSDRegister.PERM_WRITE_PROTECT | CardData->CSDRegister.TMP_WRITE_PROTECT) {
CardData->BlockIoMedia.ReadOnly = TRUE;
} else {
CardData->BlockIoMedia.ReadOnly = FALSE;
}
CardData->BlockIoMedia.WriteCaching = FALSE;
CardData->BlockIoMedia.IoAlign = 1;
Status = IndentifyDevice (CardData);
if (EFI_ERROR (Status)) {
goto Exit;
}
//
//Some device does not support this feature
//
if (CardData->IndentifyDeviceData.MaxWritesPerAddress == 0) {
CardData->BlockIoMedia.ReadOnly = TRUE;
}
CardData->BlockIoMedia.BlockSize = (1 << CardData->IndentifyDeviceData.Sectorsize);
ASSERT(CardData->BlockIoMedia.BlockSize >= 12);
MaxSize = *(UINT64*)(CardData->IndentifyDeviceData.MaximumLBA);
MaxSize = MultU64x32 (MaxSize, 512);
Remainder = 0;
CardData->BlockNumber = DivU64x32Remainder (MaxSize, CardData->BlockIoMedia.BlockSize, &Remainder);
ASSERT(Remainder == 0);
CardData->BlockIoMedia.LastBlock = (EFI_LBA)(CardData->BlockNumber - 1);
Exit:
return Status;
}

View File

@@ -0,0 +1,221 @@
/** @file
UEFI Component Name(2) protocol implementation for SD media device driver.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "SDMediaDevice.h"
//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gSDMediaDeviceName = {
SDMediaDeviceGetDriverName,
SDMediaDeviceGetControllerName,
"eng"
};
//
// EFI Component Name 2 Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gSDMediaDeviceName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SDMediaDeviceGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) SDMediaDeviceGetControllerName,
"en"
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSDMediaDeviceDriverNameTable[] = {
{ "eng;en", L"UEFI MMC/SD Media Device Driver" },
{ NULL, NULL }
};
//
// EFI Component Name Functions
//
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 3066 or ISO 639-2 language code format.
@param DriverName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
SDMediaDeviceGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
mSDMediaDeviceDriverNameTable,
DriverName,
(BOOLEAN)(This == &gSDMediaDeviceName)
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle[in] The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param ChildHandle[in] The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 3066 or ISO 639-2 language code format.
@param ControllerName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
SDMediaDeviceGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
EFI_STATUS Status;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
CARD_DATA *CardData;
//
// This is a device driver, so ChildHandle must be NULL.
//
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
}
//
// Get the device context
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiBlockIoProtocolGuid,
(VOID **) &BlockIo,
gSDMediaDeviceDriverBinding.DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
CardData = CARD_DATA_FROM_THIS (BlockIo);
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
CardData->ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gSDMediaDeviceName)
);
}

View File

@@ -0,0 +1,145 @@
/** @file
This file contains the delarations for componet name routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _COMPONENT_NAME_H_
#define _COMPONENT_NAME_H_
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 3066 or ISO 639-2 language code format.
@param DriverName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
SDMediaDeviceGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle[in] The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param ChildHandle[in] The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 3066 or ISO 639-2 language code format.
@param ControllerName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
SDMediaDeviceGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
#endif

View File

@@ -0,0 +1,544 @@
/** @file
Block I/O protocol for MMC/SD device
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "SDMediaDevice.h"
/**
Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.
@param This The EFI_BLOCK_IO_PROTOCOL instance.
@param ExtendedVerification Indicates that the driver may perform a more exhaustive.
verification operation of the device during reset.
(This parameter is ingored in this driver.)
@retval EFI_SUCCESS Success
**/
EFI_STATUS
EFIAPI
MMCSDBlockReset (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
CARD_DATA *CardData;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
CardData = CARD_DATA_FROM_THIS(This);
SDHostIo = CardData->SDHostIo;
return SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD);
}
/**
Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.
@param This The EFI_BLOCK_IO_PROTOCOL instance.
@param MediaId The media id that the write request is for.
@param LBA The starting logical block address to read from on the device.
The caller is responsible for writing to only legitimate locations.
@param BufferSize The size of the Buffer in bytes. This must be a multiple of the
intrinsic block size of the device.
@param Buffer A pointer to the destination buffer for the data. The caller
is responsible for either having implicit or explicit ownership
of the buffer.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
EFIAPI
MMCSDBlockReadBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
EFI_STATUS Status;
UINT32 Address;
CARD_DATA *CardData;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
UINT32 RemainingLength;
UINT32 TransferLength;
UINT8 *BufferPointer;
BOOLEAN SectorAddressing;
UINTN TotalBlock;
DEBUG((EFI_D_INFO, "Read(LBA=%08lx, Buffer=%08x, Size=%08x)\n", LBA, Buffer, BufferSize));
Status = EFI_SUCCESS;
CardData = CARD_DATA_FROM_THIS(This);
SDHostIo = CardData->SDHostIo;
if (MediaId != CardData->BlockIoMedia.MediaId) {
return EFI_MEDIA_CHANGED;
}
if (ModU64x32 (BufferSize,CardData->BlockIoMedia.BlockSize) != 0) {
return EFI_BAD_BUFFER_SIZE;
}
if ((CardData->CardType == SDMemoryCard2High) || (CardData->CardType == MMCCardHighCap)) {
SectorAddressing = TRUE;
} else {
SectorAddressing = FALSE;
}
if (SectorAddressing) {
//
//Block Address
//
Address = (UINT32)DivU64x32 (MultU64x32 (LBA, CardData->BlockIoMedia.BlockSize), 512);
} else {
//
//Byte Address
//
Address = (UINT32)MultU64x32 (LBA, CardData->BlockIoMedia.BlockSize);
}
TotalBlock = (UINTN) DivU64x32 (BufferSize, CardData->BlockIoMedia.BlockSize);
if (LBA + TotalBlock > CardData->BlockIoMedia.LastBlock + 1) {
return EFI_INVALID_PARAMETER;
}
if (!Buffer) {
Status = EFI_INVALID_PARAMETER;
DEBUG ((EFI_D_ERROR, "MMCSDBlockReadBlocks:Invalid parameter \r\n"));
goto Done;
}
if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {
Status = EFI_BAD_BUFFER_SIZE;
DEBUG ((EFI_D_ERROR, "MMCSDBlockReadBlocks: Bad buffer size \r\n"));
goto Done;
}
if (BufferSize == 0) {
Status = EFI_SUCCESS;
goto Done;
}
BufferPointer = Buffer;
RemainingLength = (UINT32)BufferSize;
while (RemainingLength > 0) {
if ((BufferSize > CardData->BlockIoMedia.BlockSize)) {
if (RemainingLength > SDHostIo->HostCapability.BoundarySize) {
TransferLength = SDHostIo->HostCapability.BoundarySize;
} else {
TransferLength = RemainingLength;
}
if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) {
if (!(CardData->ExtCSDRegister.CARD_TYPE & (BIT2 | BIT3))) {
Status = SendCommand (
CardData,
SET_BLOCKLEN,
CardData->BlockIoMedia.BlockSize,
NoData,
NULL,
0,
ResponseR1,
TIMEOUT_COMMAND,
(UINT32*)&(CardData->CardStatus)
);
if (EFI_ERROR (Status)) {
break;
}
}
Status = SendCommand (
CardData,
SET_BLOCK_COUNT,
TransferLength / CardData->BlockIoMedia.BlockSize,
NoData,
NULL,
0,
ResponseR1,
TIMEOUT_COMMAND,
(UINT32*)&(CardData->CardStatus)
);
if (EFI_ERROR (Status)) {
break;
}
}
Status = SendCommand (
CardData,
READ_MULTIPLE_BLOCK,
Address,
InData,
CardData->AlignedBuffer,
TransferLength,
ResponseR1,
TIMEOUT_DATA,
(UINT32*)&(CardData->CardStatus)
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "MMCSDBlockReadBlocks: READ_MULTIPLE_BLOCK -> Fail\n"));
break;
}
} else {
if (RemainingLength > CardData->BlockIoMedia.BlockSize) {
TransferLength = CardData->BlockIoMedia.BlockSize;
} else {
TransferLength = RemainingLength;
}
Status = SendCommand (
CardData,
READ_SINGLE_BLOCK,
Address,
InData,
CardData->AlignedBuffer,
(UINT32)TransferLength,
ResponseR1,
TIMEOUT_DATA,
(UINT32*)&(CardData->CardStatus)
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "MMCSDBlockReadBlocks: READ_SINGLE_BLOCK -> Fail\n"));
break;
}
}
CopyMem (BufferPointer, CardData->AlignedBuffer, TransferLength);
if (SectorAddressing) {
//
//Block Address
//
Address += TransferLength / 512;
} else {
//
//Byte Address
//
Address += TransferLength;
}
BufferPointer += TransferLength;
RemainingLength -= TransferLength;
}
if (EFI_ERROR (Status)) {
if ((CardData->CardType == SDMemoryCard) ||
(CardData->CardType == SDMemoryCard2)||
(CardData->CardType == SDMemoryCard2High)) {
SendCommand (
CardData,
STOP_TRANSMISSION,
0,
NoData,
NULL,
0,
ResponseR1b,
TIMEOUT_COMMAND,
(UINT32*)&(CardData->CardStatus)
);
} else {
SendCommand (
CardData,
STOP_TRANSMISSION,
0,
NoData,
NULL,
0,
ResponseR1,
TIMEOUT_COMMAND,
(UINT32*)&(CardData->CardStatus)
);
}
}
Done:
DEBUG((EFI_D_INFO, "MMCSDBlockReadBlocks: Status = %r\n", Status));
return Status;
}
/**
Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.
@param This The EFI_BLOCK_IO_PROTOCOL instance.
@param MediaId The media id that the write request is for.
@param LBA The starting logical block address to read from on the device.
The caller is responsible for writing to only legitimate locations.
@param BufferSize The size of the Buffer in bytes. This must be a multiple of the
intrinsic block size of the device.
@param Buffer A pointer to the destination buffer for the data. The caller
is responsible for either having implicit or explicit ownership
of the buffer.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
EFIAPI
MMCSDBlockWriteBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN UINTN BufferSize,
IN VOID *Buffer
)
{
EFI_STATUS Status;
UINT32 Address;
CARD_DATA *CardData;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
UINT32 RemainingLength;
UINT32 TransferLength;
UINT8 *BufferPointer;
BOOLEAN SectorAddressing;
DEBUG((EFI_D_INFO, "Write(LBA=%08lx, Buffer=%08x, Size=%08x)\n", LBA, Buffer, BufferSize));
Status = EFI_SUCCESS;
CardData = CARD_DATA_FROM_THIS(This);
SDHostIo = CardData->SDHostIo;
if ((CardData->CardType == SDMemoryCard2High) || (CardData->CardType == MMCCardHighCap)) {
SectorAddressing = TRUE;
} else {
SectorAddressing = FALSE;
}
if (SectorAddressing) {
//
//Block Address
//
Address = (UINT32)DivU64x32 (MultU64x32 (LBA, CardData->BlockIoMedia.BlockSize), 512);
} else {
//
//Byte Address
//
Address = (UINT32)MultU64x32 (LBA, CardData->BlockIoMedia.BlockSize);
}
if (!Buffer) {
Status = EFI_INVALID_PARAMETER;
DEBUG ((EFI_D_ERROR, "MMCSDBlockWriteBlocks: Invalid parameter \r\n"));
goto Done;
}
if ((BufferSize % CardData->BlockIoMedia.BlockSize) != 0) {
Status = EFI_BAD_BUFFER_SIZE;
DEBUG ((EFI_D_ERROR, "MMCSDBlockWriteBlocks: Bad buffer size \r\n"));
goto Done;
}
if (BufferSize == 0) {
Status = EFI_SUCCESS;
goto Done;
}
if (This->Media->ReadOnly == TRUE) {
Status = EFI_WRITE_PROTECTED;
DEBUG ((EFI_D_ERROR, "MMCSDBlockWriteBlocks: Write protected \r\n"));
goto Done;
}
BufferPointer = Buffer;
RemainingLength = (UINT32)BufferSize;
while (RemainingLength > 0) {
if ((BufferSize > CardData->BlockIoMedia.BlockSize) ) {
if (RemainingLength > SDHostIo->HostCapability.BoundarySize) {
TransferLength = SDHostIo->HostCapability.BoundarySize;
} else {
TransferLength = RemainingLength;
}
if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) {
if (!(CardData->ExtCSDRegister.CARD_TYPE & (BIT2 | BIT3))) {
Status = SendCommand (
CardData,
SET_BLOCKLEN,
CardData->BlockIoMedia.BlockSize,
NoData,
NULL,
0,
ResponseR1,
TIMEOUT_COMMAND,
(UINT32*)&(CardData->CardStatus)
);
if (EFI_ERROR (Status)) {
break;
}
}
Status = SendCommand (
CardData,
SET_BLOCK_COUNT,
TransferLength / CardData->BlockIoMedia.BlockSize,
NoData,
NULL,
0,
ResponseR1,
TIMEOUT_COMMAND,
(UINT32*)&(CardData->CardStatus)
);
if (EFI_ERROR (Status)) {
break;
}
}
CopyMem (CardData->AlignedBuffer, BufferPointer, TransferLength);
Status = SendCommand (
CardData,
WRITE_MULTIPLE_BLOCK,
Address,
OutData,
CardData->AlignedBuffer,
(UINT32)TransferLength,
ResponseR1,
TIMEOUT_DATA,
(UINT32*)&(CardData->CardStatus)
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "MMCSDBlockWriteBlocks: WRITE_MULTIPLE_BLOCK -> Fail\n"));
break;
}
} else {
if (RemainingLength > CardData->BlockIoMedia.BlockSize) {
TransferLength = CardData->BlockIoMedia.BlockSize;
} else {
TransferLength = RemainingLength;
}
CopyMem (CardData->AlignedBuffer, BufferPointer, TransferLength);
Status = SendCommand (
CardData,
WRITE_BLOCK,
Address,
OutData,
CardData->AlignedBuffer,
(UINT32)TransferLength,
ResponseR1,
TIMEOUT_DATA,
(UINT32*)&(CardData->CardStatus)
);
}
if (SectorAddressing) {
//
//Block Address
//
Address += TransferLength / 512;
} else {
//
//Byte Address
//
Address += TransferLength;
}
BufferPointer += TransferLength;
RemainingLength -= TransferLength;
}
if (EFI_ERROR (Status)) {
SendCommand (
CardData,
STOP_TRANSMISSION,
0,
NoData,
NULL,
0,
ResponseR1b,
TIMEOUT_COMMAND,
(UINT32*)&(CardData->CardStatus)
);
}
Done:
return EFI_SUCCESS;
}
/**
Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.
(In this driver, this function just returns EFI_SUCCESS.)
@param This The EFI_BLOCK_IO_PROTOCOL instance.
@retval EFI_SUCCESS
@retval Others
**/
EFI_STATUS
EFIAPI
MMCSDBlockFlushBlocks (
IN EFI_BLOCK_IO_PROTOCOL *This
)
{
return EFI_SUCCESS;
}
/**
MMC/SD card BlockIo init function.
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS
@retval Others
**/
EFI_STATUS
MMCSDBlockIoInit (
IN CARD_DATA *CardData
)
{
//
//BlockIO protocol
//
CardData->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;
CardData->BlockIo.Media = &(CardData->BlockIoMedia);
CardData->BlockIo.Reset = MMCSDBlockReset;
CardData->BlockIo.ReadBlocks = MMCSDBlockReadBlocks ;
CardData->BlockIo.WriteBlocks = MMCSDBlockWriteBlocks;
CardData->BlockIo.FlushBlocks = MMCSDBlockFlushBlocks;
CardData->BlockIoMedia.MediaId = 0;
CardData->BlockIoMedia.RemovableMedia = FALSE;
CardData->BlockIoMedia.MediaPresent = TRUE;
CardData->BlockIoMedia.LogicalPartition = FALSE;
if (CardData->CSDRegister.PERM_WRITE_PROTECT || CardData->CSDRegister.TMP_WRITE_PROTECT) {
CardData->BlockIoMedia.ReadOnly = TRUE;
} else {
CardData->BlockIoMedia.ReadOnly = FALSE;
}
CardData->BlockIoMedia.WriteCaching = FALSE;
CardData->BlockIoMedia.BlockSize = CardData->BlockLen;
CardData->BlockIoMedia.IoAlign = 1;
CardData->BlockIoMedia.LastBlock = (EFI_LBA)(CardData->BlockNumber - 1);
return EFI_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,323 @@
/** @file
The definition for SD media device driver model and blkio protocol routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "SDMediaDevice.h"
EFI_DRIVER_BINDING_PROTOCOL gSDMediaDeviceDriverBinding = {
SDMediaDeviceSupported,
SDMediaDeviceStart,
SDMediaDeviceStop,
0x20,
NULL,
NULL
};
/**
Entry point for EFI drivers.
@param ImageHandle EFI_HANDLE.
@param SystemTable EFI_SYSTEM_TABLE.
@retval EFI_SUCCESS Driver is successfully loaded.
@return Others Failed.
**/
EFI_STATUS
EFIAPI
InitializeSDMediaDevice (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&gSDMediaDeviceDriverBinding,
ImageHandle,
&gSDMediaDeviceName,
&gSDMediaDeviceName2
);
}
/**
Test to see if this driver supports ControllerHandle. Any
ControllerHandle that has BlockIoProtocol installed will be supported.
@param This Protocol instance pointer.
@param Controller Handle of device to test.
@param RemainingDevicePath Not used.
@return EFI_SUCCESS This driver supports this device.
@return EFI_UNSUPPORTED This driver does not support this device.
**/
EFI_STATUS
EFIAPI
SDMediaDeviceSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
//
// Test whether there is PCI IO Protocol attached on the controller handle.
//
Status = gBS->OpenProtocol (
Controller,
&gEfiSDHostIoProtocolGuid,
(VOID **)&SDHostIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
goto Exit;
}
gBS->CloseProtocol (
Controller,
&gEfiSDHostIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
Exit:
return Status;
}
/**
Starting the SD Media Device Driver.
@param This Protocol instance pointer.
@param Controller Handle of device to test.
@param RemainingDevicePath Not used.
@retval EFI_SUCCESS This driver supports this device.
@retval EFI_UNSUPPORTED This driver does not support this device.
@retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
**/
EFI_STATUS
EFIAPI
SDMediaDeviceStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
CARD_DATA *CardData;
CardData = NULL;
//
// Open PCI I/O Protocol and save pointer to open protocol
// in private data area.
//
Status = gBS->OpenProtocol (
Controller,
&gEfiSDHostIoProtocolGuid,
(VOID **) &SDHostIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to open gEfiSDHostIoProtocolGuid \r\n"));
goto Exit;
}
Status = SDHostIo->DetectCardAndInitHost (SDHostIo);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: Fail to DetectCardAndInitHost \r\n"));
goto Exit;
}
CardData = (CARD_DATA*)AllocateZeroPool(sizeof (CARD_DATA));
if (CardData == NULL) {
Status = EFI_OUT_OF_RESOURCES;
DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(CARD_DATA) \r\n"));
goto Exit;
}
ASSERT (SDHostIo->HostCapability.BoundarySize >= 4 * 1024);
CardData->RawBufferPointer = (UINT8*)((UINTN)DMA_MEMORY_TOP);
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiBootServicesData,
EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize),
(EFI_PHYSICAL_ADDRESS *)(&CardData->RawBufferPointer)
);
if (CardData->RawBufferPointer == NULL) {
DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to AllocateZeroPool(2*x) \r\n"));
Status = EFI_OUT_OF_RESOURCES;
goto Exit;
}
CardData->AlignedBuffer = CardData->RawBufferPointer - ((UINTN)(CardData->RawBufferPointer) & (SDHostIo->HostCapability.BoundarySize - 1)) + SDHostIo->HostCapability.BoundarySize;
CardData->Signature = CARD_DATA_SIGNATURE;
CardData->SDHostIo = SDHostIo;
Status = MMCSDCardInit (CardData);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to MMCSDCardInit \r\n"));
goto Exit;
}
DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: MMCSDCardInit SuccessFul\n"));
if (CardData->CardType == CEATACard) {
Status = CEATABlockIoInit (CardData);
} else {
Status = MMCSDBlockIoInit (CardData);
}
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to BlockIoInit \r\n"));
goto Exit;
}
DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: BlockIo is successfully installed\n"));
Status = gBS->InstallProtocolInterface (
&Controller,
&gEfiBlockIoProtocolGuid,
EFI_NATIVE_INTERFACE,
&CardData->BlockIo
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "SDMediaDeviceStart: Fail to install gEfiBlockIoProtocolGuid \r\n"));
goto Exit;
}
//
// Install the component name protocol
//
CardData->ControllerNameTable = NULL;
AddUnicodeString2 (
"eng",
gSDMediaDeviceName.SupportedLanguages,
&CardData->ControllerNameTable,
L"MMC/SD Media Device",
TRUE
);
AddUnicodeString2 (
"en",
gSDMediaDeviceName2.SupportedLanguages,
&CardData->ControllerNameTable,
L"MMC/SD Media Device",
FALSE
);
Exit:
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "SDMediaDeviceStart: End with failure\r\n"));
if (CardData != NULL) {
if (CardData->RawBufferPointer != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * SDHostIo->HostCapability.BoundarySize));
}
FreePool (CardData);
}
}
return Status;
}
/**
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
@param This Protocol instance pointer.
@param Controller Handle of device to stop driver on.
@param NumberOfChildren Number of Children in the ChildHandleBuffer.
@param ChildHandleBuffer List of handles for the children we need to stop.
@return EFI_SUCCESS
@return others
**/
EFI_STATUS
EFIAPI
SDMediaDeviceStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
CARD_DATA *CardData;
EFI_BLOCK_IO_PROTOCOL *BlockIo;
//
// First find BlockIo Protocol
//
Status = gBS->OpenProtocol (
Controller,
&gEfiBlockIoProtocolGuid,
(VOID **)&BlockIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
CardData = CARD_DATA_FROM_THIS(BlockIo);
//
// Uninstall Block I/O protocol from the device handle
//
Status = gBS->UninstallProtocolInterface (
Controller,
&gEfiBlockIoProtocolGuid,
BlockIo
);
if (EFI_ERROR (Status)) {
return Status;
}
if (CardData != NULL) {
if (CardData->RawBufferPointer != NULL) {
gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) CardData->RawBufferPointer, EFI_SIZE_TO_PAGES (2 * CardData->SDHostIo->HostCapability.BoundarySize));
}
FreeUnicodeStringTable (CardData->ControllerNameTable);
FreePool (CardData);
}
gBS->CloseProtocol (
Controller,
&gEfiSDHostIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,468 @@
/** @file
The definition for SD media device driver model and blkio protocol routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _SD_MEDIA_DEVICE_H_
#define _SD_MEDIA_DEVICE_H_
#include <Uefi.h>
#include <Protocol/PciIo.h>
#include <Protocol/BlockIo.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <IndustryStandard/Pci22.h>
#include "ComponentName.h"
#include "SDHostIo.h"
extern EFI_DRIVER_BINDING_PROTOCOL gSDMediaDeviceDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gSDMediaDeviceName;
extern EFI_COMPONENT_NAME2_PROTOCOL gSDMediaDeviceName2;
//
// Define the region of memory used for DMA memory
//
#define DMA_MEMORY_TOP 0x0000000001FFFFFFULL
#define CARD_DATA_SIGNATURE SIGNATURE_32 ('c', 'a', 'r', 'd')
//
// Command timeout will be max 100 ms
//
#define TIMEOUT_COMMAND 100
#define TIMEOUT_DATA 5000
typedef enum{
UnknownCard = 0,
MMCCard, // MMC card
MMCCardHighCap, // MMC Card High Capacity
CEATACard, // CE-ATA device
SDMemoryCard, // SD 1.1 card
SDMemoryCard2, // SD 2.0 or above standard card
SDMemoryCard2High // SD 2.0 or above high capacity card
}CARD_TYPE;
typedef struct {
//
//BlockIO
//
UINTN Signature;
EFI_BLOCK_IO_PROTOCOL BlockIo;
EFI_BLOCK_IO_MEDIA BlockIoMedia;
EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
CARD_TYPE CardType;
UINT8 CurrentBusWidth;
BOOLEAN DualVoltage;
BOOLEAN NeedFlush;
UINT8 Reserved[3];
UINT16 Address;
UINT32 BlockLen;
UINT32 MaxFrequency;
UINT64 BlockNumber;
//
//Common used
//
CARD_STATUS CardStatus;
OCR OCRRegister;
CID CIDRegister;
CSD CSDRegister;
EXT_CSD ExtCSDRegister;
UINT8 *RawBufferPointer;
UINT8 *AlignedBuffer;
//
//CE-ATA specific
//
TASK_FILE TaskFile;
IDENTIFY_DEVICE_DATA IndentifyDeviceData;
//
//SD specific
//
SCR SCRRegister;
SD_STATUS_REG SDSattus;
SWITCH_STATUS SwitchStatus;
}CARD_DATA;
#define CARD_DATA_FROM_THIS(a) \
CR(a, CARD_DATA, BlockIo, CARD_DATA_SIGNATURE)
/**
Test to see if this driver supports ControllerHandle. Any
ControllerHandle that has BlockIoProtocol installed will be supported.
@param This Protocol instance pointer.
@param Controller Handle of device to test.
@param RemainingDevicePath Not used.
@return EFI_SUCCESS This driver supports this device.
@return EFI_UNSUPPORTED This driver does not support this device.
**/
EFI_STATUS
EFIAPI
SDMediaDeviceSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Starting the SD Media Device Driver.
@param This Protocol instance pointer.
@param Controller Handle of device to test.
@param RemainingDevicePath Not used.
@retval EFI_SUCCESS This driver supports this device.
@retval EFI_UNSUPPORTED This driver does not support this device.
@retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
**/
EFI_STATUS
EFIAPI
SDMediaDeviceStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
@param This Protocol instance pointer.
@param Controller Handle of device to stop driver on.
@param NumberOfChildren Number of Children in the ChildHandleBuffer.
@param ChildHandleBuffer List of handles for the children we need to stop.
@return EFI_SUCCESS
@return others
**/
EFI_STATUS
EFIAPI
SDMediaDeviceStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
/**
MMC/SD card init function
@param CardData Pointer to CARD_DATA.
@return EFI_SUCCESS
@return others
**/
EFI_STATUS
MMCSDCardInit (
IN CARD_DATA *CardData
);
/**
Send command by using Host IO protocol
@param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
@param CommandIndex The command index to set the command index field of command register.
@param Argument Command argument to set the argument field of command register.
@param DataType TRANSFER_TYPE, indicates no data, data in or data out.
@param Buffer Contains the data read from / write to the device.
@param BufferSize The size of the buffer.
@param ResponseType RESPONSE_TYPE.
@param TimeOut Time out value in 1 ms unit.
@param ResponseData Depending on the ResponseType, such as CSD or card status.
@retval EFI_SUCCESS
@retval EFI_INVALID_PARAMETER
@retval EFI_UNSUPPORTED
@retval EFI_DEVICE_ERROR
**/
EFI_STATUS
SendCommand (
IN CARD_DATA *CardData,
IN UINT16 CommandIndex,
IN UINT32 Argument,
IN TRANSFER_TYPE DataType,
IN UINT8 *Buffer, OPTIONAL
IN UINT32 BufferSize,
IN RESPONSE_TYPE ResponseType,
IN UINT32 TimeOut,
OUT UINT32 *ResponseData
);
/**
Send the card APP_CMD command with the following command indicated by CommandIndex
@param CardData Pointer to CARD_DATA.
@param CommandIndex The command index to set the command index field of command register.
@param Argument Command argument to set the argument field of command register.
@param DataType TRANSFER_TYPE, indicates no data, data in or data out.
@param Buffer Contains the data read from / write to the device.
@param BufferSize The size of the buffer.
@param ResponseType RESPONSE_TYPE.
@param TimeOut Time out value in 1 ms unit.
@param ResponseData Depending on the ResponseType, such as CSD or card status.
@retval EFI_SUCCESS
@retval EFI_INVALID_PARAMETER
@retval EFI_UNSUPPORTED
@retval EFI_DEVICE_ERROR
**/
EFI_STATUS
SendAppCommand (
IN CARD_DATA *CardData,
IN UINT16 CommandIndex,
IN UINT32 Argument,
IN TRANSFER_TYPE DataType,
IN UINT8 *Buffer, OPTIONAL
IN UINT32 BufferSize,
IN RESPONSE_TYPE ResponseType,
IN UINT32 TimeOut,
OUT UINT32 *ResponseData
);
/**
Send the card FAST_IO command
@param CardData Pointer to CARD_DATA.
@param RegisterAddress Register Address.
@param RegisterData Pointer to register Data.
@param Write TRUE for write, FALSE for read.
@retval EFI_SUCCESS
@retval EFI_UNSUPPORTED
@retval EFI_INVALID_PARAMETER
@retval EFI_DEVICE_ERROR
**/
EFI_STATUS
FastIO (
IN CARD_DATA *CardData,
IN UINT8 RegisterAddress,
IN OUT UINT8 *RegisterData,
IN BOOLEAN Write
);
/**
Judge whether it is CE-ATA device or not.
@param CardData Pointer to CARD_DATA.
@retval TRUE
@retval FALSE
**/
BOOLEAN
IsCEATADevice (
IN CARD_DATA *CardData
);
/**
Send software reset
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
SoftwareReset (
IN CARD_DATA *CardData
);
/**
SendATACommand specificed in Taskfile
@param CardData Pointer to CARD_DATA.
@param TaskFile Pointer to TASK_FILE.
@param Write TRUE means write, FALSE means read.
@param Buffer If NULL, means no data transfer, neither read nor write.
@param SectorCount Buffer size in 512 bytes unit.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
SendATACommand (
IN CARD_DATA *CardData,
IN TASK_FILE *TaskFile,
IN BOOLEAN Write,
IN UINT8 *Buffer,
IN UINT16 SectorCount
);
/**
IDENTIFY_DEVICE command
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
IndentifyDevice (
IN CARD_DATA *CardData
);
/**
FLUSH_CACHE_EXT command
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
FlushCache (
IN CARD_DATA *CardData
);
/**
STANDBY_IMMEDIATE command
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
StandByImmediate (
IN CARD_DATA *CardData
);
/**
READ_DMA_EXT command
@param CardData Pointer to CARD_DATA.
@param LBA The starting logical block address to read from on the device.
@param Buffer A pointer to the destination buffer for the data. The caller
is responsible for either having implicit or explicit ownership
of the buffer.
@param SectorCount Size in 512 bytes unit.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
ReadDMAExt (
IN CARD_DATA *CardData,
IN EFI_LBA LBA,
IN UINT8 *Buffer,
IN UINT16 SectorCount
);
/**
WRITE_DMA_EXT command
@param CardData Pointer to CARD_DATA.
@param LBA The starting logical block address to read from on the device.
@param Buffer A pointer to the destination buffer for the data. The caller
is responsible for either having implicit or explicit ownership
of the buffer.
@param SectorCount Size in 512 bytes unit.
@retval EFI_SUCCESS Success
@retval EFI_DEVICE_ERROR Hardware Error
@retval EFI_INVALID_PARAMETER Parameter is error
@retval EFI_NO_MEDIA No media
@retval EFI_MEDIA_CHANGED Media Change
@retval EFI_BAD_BUFFER_SIZE Buffer size is bad
**/
EFI_STATUS
WriteDMAExt (
IN CARD_DATA *CardData,
IN EFI_LBA LBA,
IN UINT8 *Buffer,
IN UINT16 SectorCount
);
/**
CEATA card BlockIo init function.
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS
@retval Others
**/
EFI_STATUS
CEATABlockIoInit (
IN CARD_DATA *CardData
);
/**
MMC/SD card BlockIo init function.
@param CardData Pointer to CARD_DATA.
@retval EFI_SUCCESS
@retval Others
**/
EFI_STATUS
MMCSDBlockIoInit (
IN CARD_DATA *CardData
);
#endif

View File

@@ -0,0 +1,66 @@
## @file
#
# Component Description File For SDMediaDeviceDxe Module.
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SDMediaDevice
FILE_GUID = 80897901-91F6-4efe-9579-3353A0C02DAB
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializeSDMediaDevice
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
# DRIVER_BINDING = gSDMediaDeviceDriverBinding
# COMPONENT_NAME = gSDMediaDeviceName
# COMPONENT_NAME2 = gSDMediaDeviceName2
#
[Sources]
SDMediaDevice.c
SDMediaDevice.h
MMCSDTransfer.c
CEATA.c
CEATABlockIo.c
MMCSDBlockIo.c
ComponentName.c
ComponentName.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
QuarkSocPkg/QuarkSocPkg.dec
[LibraryClasses]
MemoryAllocationLib
BaseLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
BaseMemoryLib
DebugLib
PcdLib
[Protocols]
gEfiPciIoProtocolGuid ## TO_START
gEfiSDHostIoProtocolGuid ## TO_START
gEfiBlockIoProtocolGuid ## BY_START
[Pcd.common]

View File

@@ -0,0 +1,326 @@
/** @file
Implementation of Usb Controller PPI.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <PiPei.h>
#include <Ppi/UsbController.h>
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PcdLib.h>
#include <Library/PciLib.h>
#include <Library/IoLib.h>
#include "UsbPei.h"
//
// Globals
//
//
EFI_PEI_PPI_DESCRIPTOR mPpiList = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gPeiUsbControllerPpiGuid,
NULL
};
UINTN mIohOhciPciReg[IOH_MAX_OHCI_USB_CONTROLLERS] = {
PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_OHCI_DEVICE_NUMBER, IOH_OHCI_FUNCTION_NUMBER, 0)
};
UINTN mIohEhciPciReg[IOH_MAX_EHCI_USB_CONTROLLERS] = {
PCI_LIB_ADDRESS (IOH_USB_BUS_NUMBER, IOH_USB_EHCI_DEVICE_NUMBER, IOH_EHCI_FUNCTION_NUMBER, 0),
};
/**
When EHCI get started in DXE, OHCI couldn't get the ownership
of roothub after warm reset because CF@EHCI hasn't been cleared.
We should clear that reg before UpdateBootMode. But Reg@EHCI is
memory-mapped, so need assume a range of space without conflict
in PCI memory space.
@param[in] PeiServices The pointer of EFI_PEI_SERVICES
**/
VOID
SwitchConfigFlag (
IN EFI_PEI_SERVICES **PeiServices
)
{
UINT32 SavBaseAddr;
UINT32 UsbBaseAddr;
UINT16 SaveCmdData;
UINT8 EhciCapLen;
UINT8 Index;
UsbBaseAddr = 0;
for (Index = 0; Index < IOH_MAX_EHCI_USB_CONTROLLERS; Index++) {
UsbBaseAddr = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress);
//
// Manage EHCI on IOH, set UsbBaseAddr
//
SavBaseAddr = PciRead32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR);
PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, UsbBaseAddr);
//
// Save Cmd register
//
SaveCmdData = PciRead16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND);
//
// Enable EHCI on IOH
//
PciOr16 (mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, B_IOH_USB_COMMAND_BME | B_IOH_USB_COMMAND_MSE );
//
// Clear CF register on EHCI
//
EhciCapLen = MmioRead8 (UsbBaseAddr + R_IOH_EHCI_CAPLENGTH);
MmioWrite32 (UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS, 0);
DEBUG ((EFI_D_INFO, "CF@EHCI = %x \n", UsbBaseAddr + EhciCapLen + R_IOH_EHCI_CONFIGFLAGS));
//
// Restore EHCI UsbBaseAddr in PCI space
//
PciWrite32 (mIohEhciPciReg[Index] | R_IOH_USB_MEMBAR, SavBaseAddr);
//
// Restore EHCI Command register in PCI space
//
PciWrite16(mIohEhciPciReg[Index] | R_IOH_USB_COMMAND, SaveCmdData);
}
}
/**
Retrieved specified the USB controller information.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param This This PEI_USB_CONTROLLER_PPI instance.
@param UsbControllerId Indicate which usb controller information will be retrieved.
@param ControllerType Indicate the controller is Ehci, Ohci, OHCI
@param BaseAddress Indicate the memory bar of the controller
@retval EFI_SUCCESS The reset operation succeeded.
@retval EFI_INVALID_PARAMETER Attributes is not valid.
**/
EFI_STATUS
GetOhciController (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_CONTROLLER_PPI *This,
IN UINT8 UsbControllerId,
IN UINTN *ControllerType,
IN UINTN *BaseAddress
)
{
IOH_OHCI_DEVICE *PeiIohOhciDev;
PeiIohOhciDev = IOH_OHCI_DEVICE_FROM_THIS (This);
if (UsbControllerId >= IOH_MAX_OHCI_USB_CONTROLLERS) {
return EFI_INVALID_PARAMETER;
}
*ControllerType = PEI_OHCI_CONTROLLER;
*BaseAddress = PeiIohOhciDev->MmioBase[UsbControllerId];
return EFI_SUCCESS;
}
/**
Retrieved specified the USB controller information.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param This This PEI_USB_CONTROLLER_PPI instance.
@param UsbControllerId Indicate which usb controller information will be retrieved.
@param ControllerType Indicate the controller is Ehci, Ohci, OHCI
@param BaseAddress Indicate the memory bar of the controller
@retval EFI_SUCCESS The reset operation succeeded.
@retval EFI_INVALID_PARAMETER Attributes is not valid.
**/
EFI_STATUS
GetEhciController (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_CONTROLLER_PPI *This,
IN UINT8 UsbControllerId,
IN UINTN *ControllerType,
IN UINTN *BaseAddress
)
{
IOH_EHCI_DEVICE *PeiIohEhciDev;
PeiIohEhciDev = IOH_EHCI_DEVICE_FROM_THIS (This);
if (UsbControllerId >= IOH_MAX_EHCI_USB_CONTROLLERS) {
return EFI_INVALID_PARAMETER;
}
*ControllerType = PEI_EHCI_CONTROLLER;
*BaseAddress = PeiIohEhciDev->MmioBase[UsbControllerId];
return EFI_SUCCESS;
}
/**
Retrieved specified the USB controller information.
@param IohOhciPciReg Ohci device address list.
@param OhciCount The count of the OHCI
@param IohEhciPciReg Ehci device address list.
@param EhciCount The count of the EHCI
**/
VOID
EnableBusMaster (
IN UINTN IohOhciPciReg[],
IN UINT8 OhciCount,
IN UINTN IohEhciPciReg[],
IN UINT8 EhciCount
)
{
UINT8 Index;
UINT16 CmdReg;
for (Index = 0; Index < OhciCount; Index ++) {
CmdReg = PciRead16 (IohOhciPciReg[Index] | R_IOH_USB_COMMAND);
CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_BME );
PciWrite16 (IohOhciPciReg[Index] | R_IOH_USB_COMMAND, CmdReg);
}
for (Index = 0; Index < EhciCount; Index ++) {
CmdReg = PciRead16 (IohEhciPciReg[Index] | R_IOH_USB_COMMAND);
CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_BME );
PciWrite16 (IohEhciPciReg[Index] | R_IOH_USB_COMMAND, CmdReg);
}
}
PEI_USB_CONTROLLER_PPI mUsbControllerPpi[2] = { {GetOhciController}, {GetEhciController}};
/**
@param FileHandle Handle of the file being invoked.
@param PeiServices Describes the list of possible PEI Services.
@retval EFI_SUCCESS PPI successfully installed
**/
EFI_STATUS
PeimInitializeIchUsb (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
UINTN i;
EFI_PHYSICAL_ADDRESS AllocateAddress;
IOH_OHCI_DEVICE *PeiIohOhciDev;
IOH_EHCI_DEVICE *PeiIohEhciDev;
UINT16 CmdReg;
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
1,
&AllocateAddress
);
ASSERT_EFI_ERROR (Status);
EnableBusMaster (
mIohOhciPciReg,
IOH_MAX_OHCI_USB_CONTROLLERS,
mIohEhciPciReg,
IOH_MAX_EHCI_USB_CONTROLLERS
);
if (FeaturePcdGet (PcdEhciRecoveryEnabled)) {
DEBUG ((EFI_D_INFO, "UsbPei:EHCI is used for recovery\n"));
//
// EHCI recovery is enabled
//
PeiIohEhciDev = (IOH_EHCI_DEVICE *)((UINTN)AllocateAddress);
ZeroMem (PeiIohEhciDev, sizeof(IOH_EHCI_DEVICE));
PeiIohEhciDev->Signature = PEI_IOH_EHCI_SIGNATURE;
CopyMem(&(PeiIohEhciDev->UsbControllerPpi), &mUsbControllerPpi[1], sizeof(PEI_USB_CONTROLLER_PPI));
CopyMem(&(PeiIohEhciDev->PpiList), &mPpiList, sizeof(mPpiList));
PeiIohEhciDev->PpiList.Ppi = &PeiIohEhciDev->UsbControllerPpi;
//
// Assign resources and enable Ehci controllers
//
for (i = 0; i < IOH_MAX_EHCI_USB_CONTROLLERS; i++) {
DEBUG ((EFI_D_INFO, "UsbPei:Enable the %dth EHCI controller for recovery\n", i));
PeiIohEhciDev->MmioBase[i] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress) + IOH_USB_CONTROLLER_MMIO_RANGE * i;
//
// Assign base address register, Enable Bus Master and Memory Io
//
PciWrite32 (mIohEhciPciReg[i] | R_IOH_USB_MEMBAR, PeiIohEhciDev->MmioBase[i]);
CmdReg = PciRead16 (mIohEhciPciReg[i] | R_IOH_USB_COMMAND);
CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_MSE | B_IOH_USB_COMMAND_BME );
PciWrite16 (mIohEhciPciReg[i] | R_IOH_USB_COMMAND, CmdReg);
}
//
// Install USB Controller PPI
//
Status = (**PeiServices).InstallPpi (
PeiServices,
&PeiIohEhciDev->PpiList
);
ASSERT_EFI_ERROR (Status);
} else {
DEBUG ((EFI_D_INFO, "UsbPei:OHCI is used for recovery\n"));
//
// OHCI recovery is enabled
//
SwitchConfigFlag ((EFI_PEI_SERVICES**)PeiServices);
PeiIohOhciDev = (IOH_OHCI_DEVICE *)((UINTN)AllocateAddress);
ZeroMem (PeiIohOhciDev, sizeof(IOH_OHCI_DEVICE));
PeiIohOhciDev->Signature = PEI_IOH_OHCI_SIGNATURE;
CopyMem(&(PeiIohOhciDev->UsbControllerPpi), &mUsbControllerPpi[0], sizeof(PEI_USB_CONTROLLER_PPI));
CopyMem(&(PeiIohOhciDev->PpiList), &mPpiList, sizeof(mPpiList));
PeiIohOhciDev->PpiList.Ppi = &PeiIohOhciDev->UsbControllerPpi;
//
// Assign resources and enable OHCI controllers
//
for (i = 0; i < IOH_MAX_OHCI_USB_CONTROLLERS; i++) {
DEBUG ((EFI_D_INFO, "UsbPei:Enable the %dth OHCI controller for recovery\n", i));
PeiIohOhciDev->MmioBase[i] = PcdGet32(PcdPeiQNCUsbControllerMemoryBaseAddress) + IOH_USB_CONTROLLER_MMIO_RANGE * i;
//
// Assign base address register, Enable Bus Master and Memory Io
//
PciWrite32 (mIohOhciPciReg[i] | R_IOH_USB_MEMBAR, PeiIohOhciDev->MmioBase[i]);
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
1,
&AllocateAddress
);
ASSERT_EFI_ERROR (Status);
MmioWrite32(PeiIohOhciDev->MmioBase[i] + R_IOH_USB_OHCI_HCCABAR, (UINT32)AllocateAddress);
CmdReg = PciRead16 (mIohOhciPciReg[i] | R_IOH_USB_COMMAND);
CmdReg = (UINT16) (CmdReg | B_IOH_USB_COMMAND_MSE | B_IOH_USB_COMMAND_BME );
PciWrite16 (mIohOhciPciReg[i] | R_IOH_USB_COMMAND, CmdReg);
}
//
// Install USB Controller PPI
//
Status = (**PeiServices).InstallPpi (
PeiServices,
&PeiIohOhciDev->PpiList
);
ASSERT_EFI_ERROR (Status);
}
return Status;
}

View File

@@ -0,0 +1,44 @@
/** @file
Define private data structure for UHCI and EHCI.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _USB_PEI_H
#define _USB_PEI_H
#include "Ioh.h"
#define PEI_IOH_OHCI_SIGNATURE SIGNATURE_32 ('O', 'H', 'C', 'I')
#define PEI_IOH_EHCI_SIGNATURE SIGNATURE_32 ('E', 'H', 'C', 'I')
typedef struct {
UINTN Signature;
PEI_USB_CONTROLLER_PPI UsbControllerPpi;
EFI_PEI_PPI_DESCRIPTOR PpiList;
UINTN MmioBase[IOH_MAX_OHCI_USB_CONTROLLERS];
} IOH_OHCI_DEVICE;
typedef struct {
UINTN Signature;
PEI_USB_CONTROLLER_PPI UsbControllerPpi;
EFI_PEI_PPI_DESCRIPTOR PpiList;
UINTN MmioBase[IOH_MAX_EHCI_USB_CONTROLLERS];
} IOH_EHCI_DEVICE;
#define IOH_OHCI_DEVICE_FROM_THIS(a) \
CR(a, IOH_OHCI_DEVICE, UsbControllerPpi, PEI_IOH_OHCI_SIGNATURE)
#define IOH_EHCI_DEVICE_FROM_THIS(a) \
CR (a, IOH_EHCI_DEVICE, UsbControllerPpi, PEI_IOH_EHCI_SIGNATURE)
#endif

View File

@@ -0,0 +1,59 @@
## @file
# Component description file for UsbPei module.
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = UsbPei
FILE_GUID = 73E6F6B4-D029-4e87-8405-6067C8BD02A6
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = PeimInitializeIchUsb
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
UsbPei.c
UsbPei.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
QuarkSocPkg/QuarkSocPkg.dec
[LibraryClasses]
IoLib
PciLib
PcdLib
BaseMemoryLib
PeimEntryPoint
DebugLib
[Ppis]
gPeiUsbControllerPpiGuid # PPI ALWAYS_PRODUCED
[FeaturePcd]
gEfiQuarkSCSocIdTokenSpaceGuid.PcdEhciRecoveryEnabled
[Pcd]
gEfiQuarkSCSocIdTokenSpaceGuid.PcdPeiQNCUsbControllerMemoryBaseAddress
gEfiQuarkSCSocIdTokenSpaceGuid.PcdPeiP2PMemoryBaseAddress
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid

View File

@@ -0,0 +1,225 @@
/** @file
UEFI Component Name and Name2 protocol for OHCI driver.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Ohci.h"
//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gOhciComponentName = {
OhciComponentNameGetDriverName,
OhciComponentNameGetControllerName,
"eng"
};
//
// EFI Component Name 2 Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gOhciComponentName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) OhciComponentNameGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) OhciComponentNameGetControllerName,
"en"
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mOhciDriverNameTable[] = {
{ "eng;en", L"Usb Ohci Driver" },
{ NULL, NULL }
};
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 4646 or ISO 639-2 language code format.
@param DriverName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
OhciComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
mOhciDriverNameTable,
DriverName,
(BOOLEAN)(This == &gOhciComponentName)
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle[in] The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param ChildHandle[in] The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 4646 or ISO 639-2 language code format.
@param ControllerName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
OhciComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
EFI_STATUS Status;
USB_OHCI_HC_DEV *OhciDev;
EFI_USB_HC_PROTOCOL *UsbHc;
//
// This is a device driver, so ChildHandle must be NULL.
//
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver is currently managing ControllerHandle
//
Status = EfiTestManagedDevice (
ControllerHandle,
gOhciDriverBinding.DriverBindingHandle,
&gEfiPciIoProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the device context
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiUsbHcProtocolGuid,
(VOID **) &UsbHc,
gOhciDriverBinding.DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
OhciDev = USB_OHCI_HC_DEV_FROM_THIS (UsbHc);
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
OhciDev->ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gOhciComponentName)
);
}

View File

@@ -0,0 +1,147 @@
/** @file
This file contains the delarations for componet name routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _COMPONENT_NAME_H_
#define _COMPONENT_NAME_H_
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 4646 or ISO 639-2 language code format.
@param DriverName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
OhciComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle[in] The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param ChildHandle[in] The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 4646 or ISO 639-2 language code format.
@param ControllerName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
OhciComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
#endif

View File

@@ -0,0 +1,138 @@
/** @file
This file contains the descriptor definination of OHCI spec
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _DESCRIPTOR_H
#define _DESCRIPTOR_H
#define ED_FUNC_ADD 0x0001
#define ED_ENDPT_NUM 0x0002
#define ED_DIR 0x0004
#define ED_SPEED 0x0008
#define ED_SKIP 0x0010
#define ED_FORMAT 0x0020
#define ED_MAX_PACKET 0x0040
#define ED_TDTAIL_PTR 0x0080
#define ED_HALTED 0x0100
#define ED_DTTOGGLE 0x0200
#define ED_TDHEAD_PTR 0x0400
#define ED_NEXT_EDPTR 0x0800
#define ED_PDATA 0x1000
#define ED_ZERO 0x2000
#define TD_BUFFER_ROUND 0x0001
#define TD_DIR_PID 0x0002
#define TD_DELAY_INT 0x0004
#define TD_DT_TOGGLE 0x0008
#define TD_ERROR_CNT 0x0010
#define TD_COND_CODE 0x0020
#define TD_CURR_BUFFER_PTR 0x0040
#define TD_NEXT_PTR 0x0080
#define TD_BUFFER_END_PTR 0x0100
#define TD_PDATA 0x0200
#define ED_FROM_TD_DIR 0x0
#define ED_OUT_DIR 0x1
#define ED_IN_DIR 0x2
#define ED_FROM_TD_ALSO_DIR 0x3
#define TD_SETUP_PID 0x00
#define TD_OUT_PID 0x01
#define TD_IN_PID 0x02
#define TD_NODATA_PID 0x03
#define HI_SPEED 0
#define LO_SPEED 1
#define TD_NO_ERROR 0x00
#define TD_CRC_ERROR 0x01
#define TD_BITSTUFFING_ERROR 0x02
#define TD_TOGGLE_ERROR 0x03
#define TD_DEVICE_STALL 0x04
#define TD_NO_RESPONSE 0x05
#define TD_PIDCHK_FAIL 0x06
#define TD_PID_UNEXPECTED 0x07
#define TD_DATA_OVERRUN 0x08
#define TD_DATA_UNDERRUN 0x09
#define TD_BUFFER_OVERRUN 0x0C
#define TD_BUFFER_UNDERRUN 0x0D
#define TD_TOBE_PROCESSED 0x0E
#define TD_TOBE_PROCESSED_2 0x0F
#define TD_NO_DELAY 0x7
#define TD_INT 0x1
#define TD_CTL 0x2
#define TD_BLK 0x3
typedef struct {
UINT32 Reserved:18;
UINT32 BufferRounding:1;
UINT32 DirPID:2;
UINT32 DelayInterrupt:3;
UINT32 DataToggle:2;
UINT32 ErrorCount:2;
UINT32 ConditionCode:4;
} TD_DESCRIPTOR_WORD0;
typedef struct _TD_DESCRIPTOR {
TD_DESCRIPTOR_WORD0 Word0;
UINT32 CurrBufferPointer; // 32-bit Physical Address of buffer
UINT32 NextTD; // 32-bit Physical Address of TD_DESCRIPTOR
UINT32 BufferEndPointer; // 32-bit Physical Address of buffer
UINT32 NextTDPointer; // 32-bit Physical Address of TD_DESCRIPTOR
UINT32 DataBuffer; // 32-bit Physical Address of buffer
UINT32 ActualSendLength;
UINT32 Reserved;
} TD_DESCRIPTOR;
typedef struct {
UINT32 FunctionAddress:7;
UINT32 EndPointNum:4;
UINT32 Direction:2;
UINT32 Speed:1;
UINT32 Skip:1;
UINT32 Format:1;
UINT32 MaxPacketSize:11;
UINT32 FreeSpace:5;
} ED_DESCRIPTOR_WORD0;
typedef struct {
UINT32 Halted:1;
UINT32 ToggleCarry:1;
UINT32 Zero:2;
UINT32 TdHeadPointer:28;
} ED_DESCRIPTOR_WORD2;
typedef struct _ED_DESCRIPTOR {
ED_DESCRIPTOR_WORD0 Word0;
UINT32 TdTailPointer; // 32-bit Physical Address of TD_DESCRIPTOR
ED_DESCRIPTOR_WORD2 Word2;
UINT32 NextED; // 32-bit Physical Address of ED_DESCRIPTOR
} ED_DESCRIPTOR;
#define TD_PTR(p) ((TD_DESCRIPTOR *)(UINTN)((p) << 4))
#define ED_PTR(p) ((ED_DESCRIPTOR *)(UINTN)((p) << 4))
#define RIGHT_SHIFT_4(p) ((UINT32)(p) >> 4)
typedef enum {
CONTROL_LIST,
BULK_LIST,
INTERRUPT_LIST,
ISOCHRONOUS_LIST
} DESCRIPTOR_LIST_TYPE;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,669 @@
/** @file
Provides the definition of Usb Hc Protocol and OHCI controller
private data structure.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _OHCI_H
#define _OHCI_H
#include <Uefi.h>
#include <Protocol/UsbHostController.h>
#include <Protocol/PciIo.h>
#include <Guid/EventGroup.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <IndustryStandard/Pci.h>
typedef struct _USB_OHCI_HC_DEV USB_OHCI_HC_DEV;
#include "UsbHcMem.h"
#include "OhciReg.h"
#include "OhciSched.h"
#include "OhciUrb.h"
#include "Descriptor.h"
#include "ComponentName.h"
#include "OhciDebug.h"
extern EFI_DRIVER_BINDING_PROTOCOL gOhciDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gOhciComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gOhciComponentName2;
#define USB_OHCI_HC_DEV_SIGNATURE SIGNATURE_32('o','h','c','i')
typedef struct _HCCA_MEMORY_BLOCK{
UINT32 HccaInterruptTable[32]; // 32-bit Physical Address to ED_DESCRIPTOR
UINT16 HccaFrameNumber;
UINT16 HccaPad;
UINT32 HccaDoneHead; // 32-bit Physical Address to TD_DESCRIPTOR
UINT8 Reserved[116];
} HCCA_MEMORY_BLOCK;
struct _USB_OHCI_HC_DEV {
UINTN Signature;
EFI_USB_HC_PROTOCOL UsbHc;
EFI_USB2_HC_PROTOCOL Usb2Hc;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT64 OriginalPciAttributes;
HCCA_MEMORY_BLOCK *HccaMemoryBlock;
VOID *HccaMemoryBuf;
VOID *HccaMemoryMapping;
UINTN HccaMemoryPages;
ED_DESCRIPTOR *IntervalList[6][32];
INTERRUPT_CONTEXT_ENTRY *InterruptContextList;
VOID *MemPool;
UINT32 ToggleFlag;
EFI_EVENT HouseKeeperTimer;
//
// ExitBootServicesEvent is used to stop the OHC DMA operation
// after exit boot service.
//
EFI_EVENT ExitBootServiceEvent;
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
};
#define USB_OHCI_HC_DEV_FROM_THIS(a) CR(a, USB_OHCI_HC_DEV, UsbHc, USB_OHCI_HC_DEV_SIGNATURE)
#define USB2_OHCI_HC_DEV_FROM_THIS(a) CR(a, USB_OHCI_HC_DEV, Usb2Hc, USB_OHCI_HC_DEV_SIGNATURE)
//
// Func List
//
/**
Provides software reset for the USB host controller.
@param This This EFI_USB_HC_PROTOCOL instance.
@param Attributes A bit mask of the reset operation to perform.
@retval EFI_SUCCESS The reset operation succeeded.
@retval EFI_INVALID_PARAMETER Attributes is not valid.
@retval EFI_UNSUPPOURTED The type of reset specified by Attributes is
not currently supported by the host controller.
@retval EFI_DEVICE_ERROR Host controller isn't halted to reset.
**/
EFI_STATUS
EFIAPI
OhciReset (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT16 Attributes
);
/**
Retrieve the current state of the USB host controller.
@param This This EFI_USB_HC_PROTOCOL instance.
@param State Variable to return the current host controller
state.
@retval EFI_SUCCESS Host controller state was returned in State.
@retval EFI_INVALID_PARAMETER State is NULL.
@retval EFI_DEVICE_ERROR An error was encountered while attempting to
retrieve the host controller's current state.
**/
EFI_STATUS
EFIAPI
OhciGetState (
IN EFI_USB_HC_PROTOCOL *This,
OUT EFI_USB_HC_STATE *State
);
/**
Sets the USB host controller to a specific state.
@param This This EFI_USB_HC_PROTOCOL instance.
@param State The state of the host controller that will be set.
@retval EFI_SUCCESS The USB host controller was successfully placed
in the state specified by State.
@retval EFI_INVALID_PARAMETER State is invalid.
@retval EFI_DEVICE_ERROR Failed to set the state due to device error.
**/
EFI_STATUS
EFIAPI
OhciSetState(
IN EFI_USB_HC_PROTOCOL *This,
IN EFI_USB_HC_STATE State
);
/**
Submits control transfer to a target USB device.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
@param MaxPaketLength Indicates the maximum packet size that the
default control transfer endpoint is capable of
sending or receiving.
@param Request A pointer to the USB device request that will be sent
to the USB device.
@param TransferDirection Specifies the data direction for the transfer.
There are three values available, DataIn, DataOut
and NoData.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param DataLength Indicates the size, in bytes, of the data buffer
specified by Data.
@param TimeOut Indicates the maximum time, in microseconds,
which the transfer is allowed to complete.
@param TransferResult A pointer to the detailed result information generated
by this control transfer.
@retval EFI_SUCCESS The control transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The control transfer could not be completed due to a lack of resources.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_TIMEOUT The control transfer failed due to timeout.
@retval EFI_DEVICE_ERROR The control transfer failed due to host controller or device error.
Caller should check TranferResult for detailed error information.
--*/
EFI_STATUS
EFIAPI
OhciControlTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxPacketLength,
IN EFI_USB_DEVICE_REQUEST *Request,
IN EFI_USB_DATA_DIRECTION TransferDirection,
IN OUT VOID *Data OPTIONAL,
IN OUT UINTN *DataLength OPTIONAL,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
);
/**
Submits bulk transfer to a bulk endpoint of a USB device.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress The combination of an endpoint number and an
endpoint direction of the target USB device.
Each endpoint address supports data transfer in
one direction except the control endpoint
(whose default endpoint address is 0).
It is the caller's responsibility to make sure that
the EndPointAddress represents a bulk endpoint.
@param MaximumPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param DataLength When input, indicates the size, in bytes, of the data buffer
specified by Data. When output, indicates the actually
transferred data size.
@param DataToggle A pointer to the data toggle value. On input, it indicates
the initial data toggle value the bulk transfer should adopt;
on output, it is updated to indicate the data toggle value
of the subsequent bulk transfer.
@param TimeOut Indicates the maximum time, in microseconds, which the
transfer is allowed to complete.
TransferResult A pointer to the detailed result information of the
bulk transfer.
@retval EFI_SUCCESS The bulk transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The bulk transfer could not be submitted due to lack of resource.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_TIMEOUT The bulk transfer failed due to timeout.
@retval EFI_DEVICE_ERROR The bulk transfer failed due to host controller or device error.
Caller should check TranferResult for detailed error information.
**/
EFI_STATUS
EFIAPI
OhciBulkTransfer(
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaxPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
);
/**
Submits an interrupt transfer to an interrupt endpoint of a USB device.
@param Ohc Device private data
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress The combination of an endpoint number and an endpoint
direction of the target USB device. Each endpoint address
supports data transfer in one direction except the
control endpoint (whose default endpoint address is 0).
It is the caller's responsibility to make sure that
the EndPointAddress represents an interrupt endpoint.
@param IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
@param MaxPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
@param IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between
the host and the target interrupt endpoint.
If FALSE, the specified asynchronous interrupt pipe
is canceled.
@param DataToggle A pointer to the data toggle value. On input, it is valid
when IsNewTransfer is TRUE, and it indicates the initial
data toggle value the asynchronous interrupt transfer
should adopt.
On output, it is valid when IsNewTransfer is FALSE,
and it is updated to indicate the data toggle value of
the subsequent asynchronous interrupt transfer.
@param PollingInterval Indicates the interval, in milliseconds, that the
asynchronous interrupt transfer is polled.
This parameter is required when IsNewTransfer is TRUE.
@param UCBuffer Uncacheable buffer
@param DataLength Indicates the length of data to be received at the
rate specified by PollingInterval from the target
asynchronous interrupt endpoint. This parameter
is only required when IsNewTransfer is TRUE.
@param CallBackFunction The Callback function.This function is called at the
rate specified by PollingInterval.This parameter is
only required when IsNewTransfer is TRUE.
@param Context The context that is passed to the CallBackFunction.
This is an optional parameter and may be NULL.
@param IsPeriodic Periodic interrupt or not
@param OutputED The correspoding ED carried out
@param OutputTD The correspoding TD carried out
@retval EFI_SUCCESS The asynchronous interrupt transfer request has been successfully
submitted or canceled.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
EFI_STATUS
OhciInterruptTransfer (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle OPTIONAL,
IN UINTN PollingInterval OPTIONAL,
IN VOID *UCBuffer OPTIONAL,
IN UINTN DataLength OPTIONAL,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL,
IN VOID *Context OPTIONAL,
IN BOOLEAN IsPeriodic OPTIONAL,
OUT ED_DESCRIPTOR **OutputED OPTIONAL,
OUT TD_DESCRIPTOR **OutputTD OPTIONAL
);
/**
Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress The combination of an endpoint number and an endpoint
direction of the target USB device. Each endpoint address
supports data transfer in one direction except the
control endpoint (whose default endpoint address is 0).
It is the caller's responsibility to make sure that
the EndPointAddress represents an interrupt endpoint.
@param IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
@param MaxiumPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
@param IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between
the host and the target interrupt endpoint.
If FALSE, the specified asynchronous interrupt pipe
is canceled.
@param DataToggle A pointer to the data toggle value. On input, it is valid
when IsNewTransfer is TRUE, and it indicates the initial
data toggle value the asynchronous interrupt transfer
should adopt.
On output, it is valid when IsNewTransfer is FALSE,
and it is updated to indicate the data toggle value of
the subsequent asynchronous interrupt transfer.
@param PollingInterval Indicates the interval, in milliseconds, that the
asynchronous interrupt transfer is polled.
This parameter is required when IsNewTransfer is TRUE.
@param DataLength Indicates the length of data to be received at the
rate specified by PollingInterval from the target
asynchronous interrupt endpoint. This parameter
is only required when IsNewTransfer is TRUE.
@param CallBackFunction The Callback function.This function is called at the
rate specified by PollingInterval.This parameter is
only required when IsNewTransfer is TRUE.
@param Context The context that is passed to the CallBackFunction.
This is an optional parameter and may be NULL.
@retval EFI_SUCCESS The asynchronous interrupt transfer request has been successfully
submitted or canceled.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
**/
EFI_STATUS
EFIAPI
OhciAsyncInterruptTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle OPTIONAL,
IN UINTN PollingInterval OPTIONAL,
IN UINTN DataLength OPTIONAL,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL,
IN VOID *Context OPTIONAL
);
/**
Submits synchronous interrupt transfer to an interrupt endpoint
of a USB device.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress The combination of an endpoint number and an endpoint
direction of the target USB device. Each endpoint
address supports data transfer in one direction
except the control endpoint (whose default
endpoint address is 0). It is the caller's responsibility
to make sure that the EndPointAddress represents
an interrupt endpoint.
@param IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
@param MaxPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param DataLength On input, the size, in bytes, of the data buffer specified
by Data. On output, the number of bytes transferred.
@param DataToggle A pointer to the data toggle value. On input, it indicates
the initial data toggle value the synchronous interrupt
transfer should adopt;
on output, it is updated to indicate the data toggle value
of the subsequent synchronous interrupt transfer.
@param TimeOut Indicates the maximum time, in microseconds, which the
transfer is allowed to complete.
@param TransferResult A pointer to the detailed result information from
the synchronous interrupt transfer.
@retval EFI_UNSUPPORTED This interface not available.
@retval EFI_INVALID_PARAMETER Parameters not follow spec
**/
EFI_STATUS
EFIAPI
OhciSyncInterruptTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
);
/**
Submits isochronous transfer to a target USB device.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress End point address
@param MaximumPacketLength Indicates the maximum packet size that the
default control transfer endpoint is capable of
sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param DataLength Indicates the size, in bytes, of the data buffer
specified by Data.
@param TransferResult A pointer to the detailed result information generated
by this control transfer.
@retval EFI_UNSUPPORTED This interface not available
@retval EFI_INVALID_PARAMETER Data is NULL or DataLength is 0 or TransferResult is NULL
**/
EFI_STATUS
EFIAPI
OhciIsochronousTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN DataLength,
OUT UINT32 *TransferResult
);
/**
Submits Async isochronous transfer to a target USB device.
@param his A pointer to the EFI_USB_HC_PROTOCOL instance.
@param DeviceAddress Represents the address of the target device on the USB,
which is assigned during USB enumeration.
@param EndPointAddress End point address
@param MaximumPacketLength Indicates the maximum packet size that the
default control transfer endpoint is capable of
sending or receiving.
@param Data A pointer to the buffer of data that will be transmitted
to USB device or received from USB device.
@param IsochronousCallBack When the transfer complete, the call back function will be called
@param Context Pass to the call back function as parameter
@retval EFI_UNSUPPORTED This interface not available
@retval EFI_INVALID_PARAMETER Data is NULL or Datalength is 0
**/
EFI_STATUS
EFIAPI
OhciAsyncIsochronousTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN DataLength,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
IN VOID *Context OPTIONAL
);
/**
Retrieves the number of root hub ports.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param NumOfPorts A pointer to the number of the root hub ports.
@retval EFI_SUCCESS The port number was retrieved successfully.
**/
EFI_STATUS
EFIAPI
OhciGetRootHubNumOfPorts (
IN EFI_USB_HC_PROTOCOL *This,
OUT UINT8 *NumOfPorts
);
/**
Retrieves the current status of a USB root hub port.
@param This A pointer to the EFI_USB_HC_PROTOCOL.
@param PortNumber Specifies the root hub port from which the status
is to be retrieved. This value is zero-based. For example,
if a root hub has two ports, then the first port is numbered 0,
and the second port is numbered 1.
@param PortStatus A pointer to the current port status bits and
port status change bits.
@retval EFI_SUCCESS The status of the USB root hub port specified by PortNumber
was returned in PortStatus.
@retval EFI_INVALID_PARAMETER Port number not valid
**/
EFI_STATUS
EFIAPI
OhciGetRootHubPortStatus (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 PortNumber,
OUT EFI_USB_PORT_STATUS *PortStatus
);
/**
Sets a feature for the specified root hub port.
@param This A pointer to the EFI_USB_HC_PROTOCOL.
@param PortNumber Specifies the root hub port whose feature
is requested to be set.
@param PortFeature Indicates the feature selector associated
with the feature set request.
@retval EFI_SUCCESS The feature specified by PortFeature was set for the
USB root hub port specified by PortNumber.
@retval EFI_DEVICE_ERROR Set feature failed because of hardware issue
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
**/
EFI_STATUS
EFIAPI
OhciSetRootHubPortFeature (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
);
/**
Clears a feature for the specified root hub port.
@param This A pointer to the EFI_USB_HC_PROTOCOL instance.
@param PortNumber Specifies the root hub port whose feature
is requested to be cleared.
@param PortFeature Indicates the feature selector associated with the
feature clear request.
@retval EFI_SUCCESS The feature specified by PortFeature was cleared for the
USB root hub port specified by PortNumber.
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
@retval EFI_DEVICE_ERROR Some error happened when clearing feature
**/
EFI_STATUS
EFIAPI
OhciClearRootHubPortFeature (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
);
/**
Test to see if this driver supports ControllerHandle. Any
ControllerHandle that has UsbHcProtocol installed will be supported.
@param This Protocol instance pointer.
@param Controller Handle of device to test.
@param RemainingDevicePath Not used.
@return EFI_SUCCESS This driver supports this device.
@return EFI_UNSUPPORTED This driver does not support this device.
**/
EFI_STATUS
EFIAPI
OHCIDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Starting the Usb OHCI Driver.
@param This Protocol instance pointer.
@param Controller Handle of device to test.
@param RemainingDevicePath Not used.
@retval EFI_SUCCESS This driver supports this device.
@retval EFI_UNSUPPORTED This driver does not support this device.
@retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
**/
EFI_STATUS
EFIAPI
OHCIDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
@param This Protocol instance pointer.
@param Controller Handle of device to stop driver on.
@param NumberOfChildren Number of Children in the ChildHandleBuffer.
@param ChildHandleBuffer List of handles for the children we need to stop.
@return EFI_SUCCESS
@return others
**/
EFI_STATUS
EFIAPI
OHCIDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
#endif

View File

@@ -0,0 +1,84 @@
/** @file
This file provides the information dump support for OHCI when in debug mode.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Ohci.h"
/*++
Print the data of ED and the TDs attached to the ED
@param Uhc Pointer to OHCI private data
@param Ed Pointer to a ED to free
@param Td Pointer to the Td head
@retval EFI_SUCCESS ED
**/
EFI_STATUS
OhciDumpEdTdInfo (
IN USB_OHCI_HC_DEV *Uhc,
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *Td,
BOOLEAN Stage
)
{
UINT32 Index;
if (Stage) {
DEBUG ((EFI_D_INFO, "\n Before executing command\n"));
}else{
DEBUG ((EFI_D_INFO, "\n after executing command\n"));
}
if (Ed != NULL) {
DEBUG ((EFI_D_INFO, "\nED Address:%p, ED buffer:\n", Ed));
DEBUG ((EFI_D_INFO, "DWord0 :TD Tail :TD Head :Next ED\n"));
for (Index = 0; Index < sizeof (ED_DESCRIPTOR)/4; Index ++) {
DEBUG ((EFI_D_INFO, "%8x ", *((UINT32*)(Ed) + Index) ));
}
DEBUG ((EFI_D_INFO, "\nNext TD buffer:%p\n", Td));
}
while (Td != NULL) {
if (Td->Word0.DirPID == TD_SETUP_PID) {
DEBUG ((EFI_D_INFO, "\nSetup PID "));
}else if (Td->Word0.DirPID == TD_OUT_PID) {
DEBUG ((EFI_D_INFO, "\nOut PID "));
}else if (Td->Word0.DirPID == TD_IN_PID) {
DEBUG ((EFI_D_INFO, "\nIn PID "));
}else if (Td->Word0.DirPID == TD_NODATA_PID) {
DEBUG ((EFI_D_INFO, "\nNo data PID "));
}
DEBUG ((EFI_D_INFO, "TD Address:%p, TD buffer:\n", Td));
DEBUG ((EFI_D_INFO, "DWord0 :CuBuffer:Next TD :Buff End:Next TD :DataBuff:ActLength\n"));
for (Index = 0; Index < sizeof (TD_DESCRIPTOR)/4; Index ++) {
DEBUG ((EFI_D_INFO, "%8x ", *((UINT32*)(Td) + Index) ));
}
DEBUG ((EFI_D_INFO, "\nCurrent TD Data buffer(size%d)\n", (UINT32)Td->ActualSendLength));
for (Index = 0; Index < Td->ActualSendLength; Index ++) {
DEBUG ((EFI_D_INFO, "%2x ", *(UINT8 *)(UINTN)(Td->DataBuffer + Index) ));
}
Td = (TD_DESCRIPTOR *)(UINTN)(Td->NextTDPointer);
}
DEBUG ((EFI_D_INFO, "\n TD buffer End\n"));
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,48 @@
/** @file
This file contains the definination for host controller
debug support routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
/*++
Routine Description:
Print the data of ED and the TDs attached to the ED
@param Uhc Pointer to OHCI private data
@param Ed Pointer to a ED to free
@param Td Pointer to the Td head
@retval EFI_SUCCESS ED
**/
EFI_STATUS
OhciDumpEdTdInfo (
IN USB_OHCI_HC_DEV *Uhc,
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *Td,
BOOLEAN Stage
);

View File

@@ -0,0 +1,77 @@
## @file
# OHCI USB Host Controller UEFI Driver
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = OhciDxe
FILE_GUID = 4ACA697E-F883-446f-98F7-096416FFFFFF
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = OHCIDriverEntryPoint
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
# DRIVER_BINDING = gOhciDriverBinding
# COMPONENT_NAME = gOhciComponentName
# COMPONENT_NAME2 = gOhciComponentName2
#
[Sources]
Descriptor.h
Ohci.c
Ohci.h
OhciSched.c
OhciSched.h
OhciReg.c
OhciReg.h
OhciUrb.c
OhciUrb.h
OhciDebug.c
OhciDebug.h
ComponentName.c
ComponentName.h
UsbHcMem.c
UsbHcMem.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
QuarkSocPkg/QuarkSocPkg.dec
[LibraryClasses]
MemoryAllocationLib
BaseLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
BaseMemoryLib
DebugLib
[Guids]
gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event
[Protocols]
gEfiPciIoProtocolGuid ## TO_START
gEfiUsbHcProtocolGuid ## BY_START
#
# [Event]
# ##
# # Periodic timer event for checking the result of interrupt transfer execution.
# #
# EVENT_TYPE_PERIODIC_TIMER ## CONSUMES
#

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,926 @@
/** @file
This file contains the definination for host controller
register operation routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _OHCI_REG_H
#define _OHCI_REG_H
#define HC_STATE_RESET 0x0
#define HC_STATE_RESUME 0x1
#define HC_STATE_OPERATIONAL 0x2
#define HC_STATE_SUSPEND 0x3
#define PERIODIC_ENABLE 0x01
#define ISOCHRONOUS_ENABLE 0x02
#define CONTROL_ENABLE 0x04
#define BULK_ENABLE 0x08
#define CONTROL_BULK_RATIO 0x10
#define HC_FUNCTIONAL_STATE 0x20
#define INTERRUPT_ROUTING 0x40
#define HC_RESET 0x01
#define CONTROL_LIST_FILLED 0x02
#define BULK_LIST_FILLED 0x04
#define CHANGE_OWNER_REQUEST 0x08
#define SCHEDULE_OVERRUN_COUNT 0x10
#define SCHEDULE_OVERRUN 0x00001
#define WRITEBACK_DONE_HEAD 0x00002
#define START_OF_FRAME 0x00004
#define RESUME_DETECT 0x00008
#define UNRECOVERABLE_ERROR 0x00010
#define FRAME_NUMBER_OVERFLOW 0x00020
#define ROOTHUB_STATUS_CHANGE 0x00040
#define OWNERSHIP_CHANGE 0x00080
#define MASTER_INTERRUPT 0x00400
#define CONTROL_HEAD 0x001
#define BULK_HEAD 0x002
#define DONE_HEAD 0x004
#define Hc_HCCA 0x001
#define Hc_PERIODIC_CURRENT 0x002
#define Hc_CONTOL_HEAD 0x004
#define Hc_CONTROL_CURRENT_PTR 0x008
#define Hc_BULK_HEAD 0x010
#define Hc_BULK_CURRENT_PTR 0x020
#define Hc_DONE_HEAD 0x040
#define FRAME_INTERVAL 0x008
#define FS_LARGEST_DATA_PACKET 0x010
#define FRMINT_TOGGLE 0x020
#define FRAME_REMAINING 0x040
#define FRAME_REMAIN_TOGGLE 0x080
#define RH_DESC_A 0x00001
#define RH_DESC_B 0x00002
#define RH_NUM_DS_PORTS 0x00004
#define RH_NO_PSWITCH 0x00008
#define RH_PSWITCH_MODE 0x00010
#define RH_DEVICE_TYPE 0x00020
#define RH_OC_PROT_MODE 0x00040
#define RH_NOC_PROT 0x00080
#define RH_POTPGT 0x00100
#define RH_NO_POTPGT 0x00200
#define RH_DEV_REMOVABLE 0x00400
#define RH_PORT_PWR_CTRL_MASK 0x00800
#define RH_LOCAL_PSTAT 0x00001
#define RH_OC_ID 0x00002
#define RH_REMOTE_WK_ENABLE 0x00004
#define RH_LOCAL_PSTAT_CHANGE 0x00008
#define RH_OC_ID_CHANGE 0x00010
#define RH_CLR_RMT_WK_ENABLE 0x00020
#define RH_CLEAR_PORT_ENABLE 0x0001
#define RH_SET_PORT_ENABLE 0x0002
#define RH_SET_PORT_SUSPEND 0x0004
#define RH_CLEAR_SUSPEND_STATUS 0x0008
#define RH_SET_PORT_RESET 0x0010
#define RH_SET_PORT_POWER 0x0020
#define RH_CLEAR_PORT_POWER 0x0040
#define RH_CONNECT_STATUS_CHANGE 0x10000
#define RH_PORT_ENABLE_STAT_CHANGE 0x20000
#define RH_PORT_SUSPEND_STAT_CHANGE 0x40000
#define RH_OC_INDICATOR_CHANGE 0x80000
#define RH_PORT_RESET_STAT_CHANGE 0x100000
#define RH_CURR_CONNECT_STAT 0x0001
#define RH_PORT_ENABLE_STAT 0x0002
#define RH_PORT_SUSPEND_STAT 0x0004
#define RH_PORT_OC_INDICATOR 0x0008
#define RH_PORT_RESET_STAT 0x0010
#define RH_PORT_POWER_STAT 0x0020
#define RH_LSDEVICE_ATTACHED 0x0040
#define RESET_SYSTEM_BUS (1 << 0)
#define RESET_HOST_CONTROLLER (1 << 1)
#define RESET_CLOCK_GENERATION (1 << 2)
#define RESET_SSE_GLOBAL (1 << 5)
#define RESET_PSPL (1 << 6)
#define RESET_PCPL (1 << 7)
#define RESET_SSEP1 (1 << 9)
#define RESET_SSEP2 (1 << 10)
#define RESET_SSEP3 (1 << 11)
#define ONE_SECOND 1000000
#define ONE_MILLI_SEC 1000
#define MAX_BYTES_PER_TD 0x1000
#define MAX_RETRY_TIMES 100
#define PORT_NUMBER_ON_MAINSTONE2 1
//
// Operational Register Offsets
//
//
// Command & Status Registers Offsets
//
#define HC_REVISION 0x00
#define HC_CONTROL 0x04
#define HC_COMMAND_STATUS 0x08
#define HC_INTERRUPT_STATUS 0x0C
#define HC_INTERRUPT_ENABLE 0x10
#define HC_INTERRUPT_DISABLE 0x14
//
// Memory Pointer Offsets
//
#define HC_HCCA 0x18
#define HC_PERIODIC_CURRENT 0x1C
#define HC_CONTROL_HEAD 0x20
#define HC_CONTROL_CURRENT_PTR 0x24
#define HC_BULK_HEAD 0x28
#define HC_BULK_CURRENT_PTR 0x2C
#define HC_DONE_HEAD 0x30
//
// Frame Register Offsets
//
#define HC_FRM_INTERVAL 0x34
#define HC_FRM_REMAINING 0x38
#define HC_FRM_NUMBER 0x3C
#define HC_PERIODIC_START 0x40
#define HC_LS_THREASHOLD 0x44
//
// Root Hub Register Offsets
//
#define HC_RH_DESC_A 0x48
#define HC_RH_DESC_B 0x4C
#define HC_RH_STATUS 0x50
#define HC_RH_PORT_STATUS 0x54
#define USBHOST_OFFSET_UHCHR 0x64 // Usb Host reset register
#define OHC_BAR_INDEX 0
//
// Usb Host controller register offset
//
#define USBHOST_OFFSET_UHCREV 0x0 // Usb Host revision register
#define USBHOST_OFFSET_UHCHCON 0x4 // Usb Host control register
#define USBHOST_OFFSET_UHCCOMS 0x8 // Usb Host Command Status register
#define USBHOST_OFFSET_UHCINTS 0xC // Usb Host Interrupt Status register
#define USBHOST_OFFSET_UHCINTE 0x10 // Usb Host Interrupt Enable register
#define USBHOST_OFFSET_UHCINTD 0x14 // Usb Host Interrupt Disable register
#define USBHOST_OFFSET_UHCHCCA 0x18 // Usb Host Controller Communication Area
#define USBHOST_OFFSET_UHCPCED 0x1C // Usb Host Period Current Endpoint Descriptor
#define USBHOST_OFFSET_UHCCHED 0x20 // Usb Host Control Head Endpoint Descriptor
#define USBHOST_OFFSET_UHCCCED 0x24 // Usb Host Control Current Endpoint Descriptor
#define USBHOST_OFFSET_UHCBHED 0x28 // Usb Host Bulk Head Endpoint Descriptor
#define USBHOST_OFFSET_UHCBCED 0x2C // Usb Host Bulk Current Endpoint Descriptor
#define USBHOST_OFFSET_UHCDHEAD 0x30 // Usb Host Done Head register
#define USBHOST_OFFSET_UHCFMI 0x34 // Usb Host Frame Interval register
#define USBHOST_OFFSET_UHCFMR 0x38 // Usb Host Frame Remaining register
#define USBHOST_OFFSET_UHCFMN 0x3C // Usb Host Frame Number register
#define USBHOST_OFFSET_UHCPERS 0x40 // Usb Host Periodic Start register
#define USBHOST_OFFSET_UHCLST 0x44 // Usb Host Low-Speed Threshold register
#define USBHOST_OFFSET_UHCRHDA 0x48 // Usb Host Root Hub Descriptor A register
#define USBHOST_OFFSET_UHCRHDB 0x4C // Usb Host Root Hub Descriptor B register
#define USBHOST_OFFSET_UHCRHS 0x50 // Usb Host Root Hub Status register
#define USBHOST_OFFSET_UHCRHPS1 0x54 // Usb Host Root Hub Port Status 1 register
//
// Usb Host controller register bit fields
//
#pragma pack(1)
typedef struct {
UINT8 ProgInterface;
UINT8 SubClassCode;
UINT8 BaseCode;
} USB_CLASSC;
typedef struct {
UINT32 Revision:8;
UINT32 Rsvd:24;
} HcREVISION;
typedef struct {
UINT32 ControlBulkRatio:2;
UINT32 PeriodicEnable:1;
UINT32 IsochronousEnable:1;
UINT32 ControlEnable:1;
UINT32 BulkEnable:1;
UINT32 FunctionalState:2;
UINT32 InterruptRouting:1;
UINT32 RemoteWakeup:1;
UINT32 RemoteWakeupEnable:1;
UINT32 Reserved:21;
} HcCONTROL;
typedef struct {
UINT32 HcReset:1;
UINT32 ControlListFilled:1;
UINT32 BulkListFilled:1;
UINT32 ChangeOwnerRequest:1;
UINT32 Reserved1:12;
UINT32 ScheduleOverrunCount:2;
UINT32 Reserved:14;
} HcCOMMAND_STATUS;
typedef struct {
UINT32 SchedulingOverrun:1;
UINT32 WriteBackDone:1;
UINT32 Sof:1;
UINT32 ResumeDetected:1;
UINT32 UnrecoverableError:1;
UINT32 FrameNumOverflow:1;
UINT32 RHStatusChange:1;
UINT32 Reserved1:23;
UINT32 OwnerChange:1;
UINT32 Reserved2:1;
} HcINTERRUPT_STATUS;
typedef struct {
UINT32 SchedulingOverrunInt:1;
UINT32 WriteBackDoneInt:1;
UINT32 SofInt:1;
UINT32 ResumeDetectedInt:1;
UINT32 UnrecoverableErrorInt:1;
UINT32 FrameNumOverflowInt:1;
UINT32 RHStatusChangeInt:1;
UINT32 Reserved:23;
UINT32 OwnerChangedInt:1;
UINT32 MasterInterruptEnable:1;
} HcINTERRUPT_CONTROL;
typedef struct {
UINT32 Rerserved:8;
UINT32 Hcca:24;
} HcHCCA;
typedef struct {
UINT32 Reserved:4;
UINT32 MemoryPtr:28;
} HcMEMORY_PTR;
typedef struct {
UINT32 FrameInterval:14;
UINT32 Reserved:2;
UINT32 FSMaxDataPacket:15;
UINT32 FrmIntervalToggle:1;
} HcFRM_INTERVAL;
typedef struct {
UINT32 FrameRemaining:14;
UINT32 Reserved:17;
UINT32 FrameRemainingToggle:1;
} HcFRAME_REMAINING;
typedef struct {
UINT32 FrameNumber:16;
UINT32 Reserved:16;
} HcFRAME_NUMBER;
typedef struct {
UINT32 PeriodicStart:14;
UINT32 Reserved:18;
} HcPERIODIC_START;
typedef struct {
UINT32 LsThreshold:12;
UINT32 Reserved:20;
} HcLS_THRESHOLD;
typedef struct {
UINT32 NumDownStrmPorts:8;
UINT32 PowerSwitchMode:1;
UINT32 NoPowerSwitch:1;
UINT32 DeviceType:1;
UINT32 OverCurrentProtMode:1;
UINT32 NoOverCurrentProtMode:1;
UINT32 Reserved:11;
UINT32 PowerOnToPowerGoodTime:8;
} HcRH_DESC_A;
typedef struct {
UINT32 DeviceRemovable:16;
UINT32 PortPowerControlMask:16;
} HcRH_DESC_B;
typedef struct {
UINT32 LocalPowerStat:1;
UINT32 OverCurrentIndicator:1;
UINT32 Reserved1:13;
UINT32 DevRemoteWakeupEnable:1;
UINT32 LocalPowerStatChange:1;
UINT32 OverCurrentIndicatorChange:1;
UINT32 Reserved2:13;
UINT32 ClearRemoteWakeupEnable:1;
} HcRH_STATUS;
typedef struct {
UINT32 CurrentConnectStat:1;
UINT32 EnableStat:1;
UINT32 SuspendStat:1;
UINT32 OCIndicator:1;
UINT32 ResetStat:1;
UINT32 Reserved1:3;
UINT32 PowerStat:1;
UINT32 LsDeviceAttached:1;
UINT32 Reserved2:6;
UINT32 ConnectStatChange:1;
UINT32 EnableStatChange:1;
UINT32 SuspendStatChange:1;
UINT32 OCIndicatorChange:1;
UINT32 ResetStatChange:1;
UINT32 Reserved3:11;
} HcRHPORT_STATUS;
typedef struct {
UINT32 FSBIR:1;
UINT32 FHR:1;
UINT32 CGR:1;
UINT32 SSDC:1;
UINT32 UIT:1;
UINT32 SSE:1;
UINT32 PSPL:1;
UINT32 PCPL:1;
UINT32 Reserved0:1;
UINT32 SSEP1:1;
UINT32 SSEP2:1;
UINT32 SSEP3:1;
UINT32 Reserved1:20;
} HcRESET;
#pragma pack()
//
// Func List
//
/**
Get OHCI operational reg value
@param PciIo PciIo protocol instance
@param Offset Offset of the operational reg
@retval Value of the register
**/
UINT32
OhciGetOperationalReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 Offset
);
/**
Set OHCI operational reg value
@param PciIo PCI Bus Io protocol instance
@param Offset Offset of the operational reg
@param Value Value to set
@retval EFI_SUCCESS Value set to the reg
**/
EFI_STATUS
OhciSetOperationalReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 Offset,
IN VOID *Value
);
/**
Get HcRevision reg value
@param PciIo PCI Bus Io protocol instance
@retval Value of the register
**/
UINT32
OhciGetHcRevision (
IN EFI_PCI_IO_PROTOCOL *PciIo
);
/**
Set HcReset reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcReset (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Field,
IN UINT32 Value
);
/**
Get specific field of HcReset reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcReset (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Field
);
/**
Set HcControl reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
);
/**
Get specific field of HcControl reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set HcCommand reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcCommandStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
);
/**
Get specific field of HcCommand reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcCommandStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Clear specific fields of Interrupt Status
@param Ohc UHC private data
@param Field Field to clear
@retval EFI_SUCCESS Fields cleared
**/
EFI_STATUS
OhciClearInterruptStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Get fields of HcInterrupt reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcInterruptStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set Interrupt Control reg value
@param Ohc UHC private data
@param StatEnable Enable or Disable
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetInterruptControl (
IN USB_OHCI_HC_DEV *Ohc,
IN BOOLEAN StatEnable,
IN UINTN Field,
IN UINT32 Value
);
/**
Get field of HcInterruptControl reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcInterruptControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set memory pointer of specific type
@param Ohc UHC private data
@param PointerType Type of the pointer to set
@param Value Value to set
@retval EFI_SUCCESS Memory pointer set
**/
EFI_STATUS
OhciSetMemoryPointer(
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 PointerType,
IN VOID *Value
);
/**
Get memory pointer of specific type
@param Ohc UHC private data
@param PointerType Type of pointer
@retval Memory pointer of the specific type
**/
VOID *
OhciGetMemoryPointer (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 PointerType
);
/**
Set Frame Interval value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameInterval (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
);
/**
Get field of frame interval reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetFrameInterval (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set Frame Remaining reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameRemaining (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
);
/**
Get value of frame remaining reg
@param Ohc UHC private data
@param Field Field to get
@retval Value of frame remaining reg
**/
UINT32
OhciGetFrameRemaining (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set frame number reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameNumber(
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
);
/**
Get frame number reg value
@param Ohc UHC private data
@retval Value of frame number reg
**/
UINT32
OhciGetFrameNumber (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Set period start reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetPeriodicStart (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
);
/**
Get periodic start reg value
@param Ohc UHC private data
@param Value of periodic start reg
**/
UINT32
OhciGetPeriodicStart (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Set Ls Threshold reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetLsThreshold (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
);
/**
Get Ls Threshold reg value
@param Ohc UHC private data
@retval Value of Ls Threshold reg
**/
UINT32
OhciGetLsThreshold (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Set Root Hub Descriptor reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubDescriptor (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
);
/**
Get Root Hub Descriptor reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetRootHubDescriptor (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set Root Hub Status reg value
@param Ohc UHC private data
@param Field Field to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Get Root Hub Status reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetRootHubStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set Root Hub Port Status reg value
@param Ohc UHC private data
@param Index Index of the port
@param Field Field to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubPortStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Index,
IN UINTN Field
);
/**
Get Root Hub Port Status reg value
@param Ohc UHC private data
@param Index Index of the port
@param Field Field to get
@retval Value of the field and index
**/
UINT32
OhciReadRootHubPortStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Index,
IN UINTN Field
);
#endif

View File

@@ -0,0 +1,534 @@
/** @file
OHCI transfer scheduling routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Ohci.h"
/**
Add an item of interrupt context
@param Ohc UHC private data
@param NewEntry New entry to add
@retval EFI_SUCCESS Item successfully added
**/
EFI_STATUS
OhciAddInterruptContextEntry (
IN USB_OHCI_HC_DEV *Ohc,
IN INTERRUPT_CONTEXT_ENTRY *NewEntry
)
{
INTERRUPT_CONTEXT_ENTRY *Entry;
EFI_TPL OriginalTPL;
OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
if (Ohc->InterruptContextList == NULL) {
Ohc->InterruptContextList = NewEntry;
} else {
Entry = Ohc->InterruptContextList;
while (Entry->NextEntry != NULL) {
Entry = Entry->NextEntry;
}
Entry->NextEntry = NewEntry;
}
gBS->RestoreTPL (OriginalTPL);
return EFI_SUCCESS;
}
/**
Free a interrupt context entry
@param Ohc UHC private data
@param Entry Pointer to an interrupt context entry
@retval EFI_SUCCESS Entry freed
@retval EFI_INVALID_PARAMETER Entry is NULL
**/
EFI_STATUS
OhciFreeInterruptContextEntry (
IN USB_OHCI_HC_DEV *Ohc,
IN INTERRUPT_CONTEXT_ENTRY *Entry
)
{
TD_DESCRIPTOR *Td;
if (Entry == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Entry->UCBufferMapping != NULL) {
Ohc->PciIo->Unmap(Ohc->PciIo, Entry->UCBufferMapping);
}
if (Entry->UCBuffer != NULL) {
FreePool(Entry->UCBuffer);
}
while (Entry->DataTd) {
Td = Entry->DataTd;
Entry->DataTd = (TD_DESCRIPTOR *)(UINTN)(Entry->DataTd->NextTDPointer);
UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));
}
FreePool(Entry);
return EFI_SUCCESS;
}
/**
Free entries match the device address and endpoint address
@Param Ohc UHC private date
@Param DeviceAddress Item to free must match this device address
@Param EndPointAddress Item to free must match this end point address
@Param DataToggle DataToggle for output
@retval EFI_SUCCESS Items match the requirement removed
**/
EFI_STATUS
OhciFreeInterruptContext(
IN USB_OHCI_HC_DEV *Ohc,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
OUT UINT8 *DataToggle
)
{
INTERRUPT_CONTEXT_ENTRY *Entry;
INTERRUPT_CONTEXT_ENTRY *TempEntry;
EFI_TPL OriginalTPL;
OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);
while (Ohc->InterruptContextList != NULL &&
Ohc->InterruptContextList->DeviceAddress == DeviceAddress &&
Ohc->InterruptContextList->EndPointAddress == EndPointAddress) {
TempEntry = Ohc->InterruptContextList;
Ohc->InterruptContextList = Ohc->InterruptContextList->NextEntry;
if (DataToggle != NULL) {
*DataToggle = (UINT8) (TempEntry->DataTd->Word0.DataToggle & 0x1);
}
OhciFreeInterruptContextEntry (Ohc, TempEntry);
}
Entry = Ohc->InterruptContextList;
if (Entry == NULL) {
gBS->RestoreTPL (OriginalTPL);
return EFI_SUCCESS;
}
while (Entry->NextEntry != NULL) {
if (Entry->NextEntry->DeviceAddress == DeviceAddress &&
Entry->NextEntry->EndPointAddress == EndPointAddress) {
TempEntry = Entry->NextEntry;
Entry->NextEntry = Entry->NextEntry->NextEntry;
if (DataToggle != NULL) {
*DataToggle = (UINT8) (TempEntry->DataTd->Word0.DataToggle & 0x1);
}
OhciFreeInterruptContextEntry (Ohc, TempEntry);
} else {
Entry = Entry->NextEntry;
}
}
gBS->RestoreTPL (OriginalTPL);
return EFI_SUCCESS;
}
/**
Convert Error code from OHCI format to EFI format
@Param ErrorCode ErrorCode in OHCI format
@retval ErrorCode in EFI format
**/
UINT32
ConvertErrorCode (
IN UINT32 ErrorCode
)
{
UINT32 TransferResult;
switch (ErrorCode) {
case TD_NO_ERROR:
TransferResult = EFI_USB_NOERROR;
break;
case TD_TOBE_PROCESSED:
case TD_TOBE_PROCESSED_2:
TransferResult = EFI_USB_ERR_NOTEXECUTE;
break;
case TD_DEVICE_STALL:
TransferResult = EFI_USB_ERR_STALL;
break;
case TD_BUFFER_OVERRUN:
case TD_BUFFER_UNDERRUN:
TransferResult = EFI_USB_ERR_BUFFER;
break;
case TD_CRC_ERROR:
TransferResult = EFI_USB_ERR_CRC;
break;
case TD_NO_RESPONSE:
TransferResult = EFI_USB_ERR_TIMEOUT;
break;
case TD_BITSTUFFING_ERROR:
TransferResult = EFI_USB_ERR_BITSTUFF;
break;
default:
TransferResult = EFI_USB_ERR_SYSTEM;
}
return TransferResult;
}
/**
Check TDs Results
@Param Ohc UHC private data
@Param Td TD_DESCRIPTOR
@Param Result Result to return
@retval TRUE means OK
@retval FLASE means Error or Short packet
**/
BOOLEAN
OhciCheckTDsResults (
IN USB_OHCI_HC_DEV *Ohc,
IN TD_DESCRIPTOR *Td,
OUT UINT32 *Result
)
{
UINT32 TdCompletionCode;
*Result = EFI_USB_NOERROR;
while (Td) {
TdCompletionCode = Td->Word0.ConditionCode;
*Result |= ConvertErrorCode(TdCompletionCode);
//
// if any error encountered, stop processing the left TDs.
//
if (*Result) {
return FALSE;
}
Td = (TD_DESCRIPTOR *)(UINTN)(Td->NextTDPointer);
}
return TRUE;
}
/**
Check the task status on an ED
@Param Ed Pointer to the ED task that TD hooked on
@Param HeadTd TD header for current transaction
@retval Task Status Code
**/
UINT32
CheckEDStatus (
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd,
OUT OHCI_ED_RESULT *EdResult
)
{
while(HeadTd != NULL) {
if (HeadTd->NextTDPointer == 0) {
return TD_NO_ERROR;
}
if (HeadTd->Word0.ConditionCode != 0) {
return HeadTd->Word0.ConditionCode;
}
EdResult->NextToggle = ((UINT8)(HeadTd->Word0.DataToggle) & BIT0) ^ BIT0;
HeadTd = (TD_DESCRIPTOR *)(UINTN)(HeadTd->NextTDPointer);
}
if (OhciGetEDField (Ed, ED_TDHEAD_PTR) != OhciGetEDField (Ed, ED_TDTAIL_PTR)) {
return TD_TOBE_PROCESSED;
}
return TD_NO_ERROR;
}
/**
Check the task status
@Param Ohc UHC private data
@Param ListType Pipe type
@Param Ed Pointer to the ED task hooked on
@Param HeadTd Head of TD corresponding to the task
@Param ErrorCode return the ErrorCode
@retval EFI_SUCCESS Task done
@retval EFI_NOT_READY Task on processing
@retval EFI_DEVICE_ERROR Some error occured
**/
EFI_STATUS
CheckIfDone (
IN USB_OHCI_HC_DEV *Ohc,
IN DESCRIPTOR_LIST_TYPE ListType,
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd,
OUT OHCI_ED_RESULT *EdResult
)
{
EdResult->ErrorCode = TD_TOBE_PROCESSED;
switch (ListType) {
case CONTROL_LIST:
if (OhciGetHcCommandStatus (Ohc, CONTROL_LIST_FILLED) != 0) {
return EFI_NOT_READY;
}
break;
case BULK_LIST:
if (OhciGetHcCommandStatus (Ohc, BULK_LIST_FILLED) != 0) {
return EFI_NOT_READY;
}
break;
default:
break;
}
EdResult->ErrorCode = CheckEDStatus (Ed, HeadTd, EdResult);
if (EdResult->ErrorCode == TD_NO_ERROR) {
return EFI_SUCCESS;
} else if (EdResult->ErrorCode == TD_TOBE_PROCESSED) {
return EFI_NOT_READY;
} else {
return EFI_DEVICE_ERROR;
}
}
/**
Convert TD condition code to Efi Status
@Param ConditionCode Condition code to convert
@retval EFI_SUCCESS No error occured
@retval EFI_NOT_READY TD still on processing
@retval EFI_DEVICE_ERROR Error occured in processing TD
**/
EFI_STATUS
OhciTDConditionCodeToStatus (
IN UINT32 ConditionCode
)
{
if (ConditionCode == TD_NO_ERROR) {
return EFI_SUCCESS;
}
if (ConditionCode == TD_TOBE_PROCESSED) {
return EFI_NOT_READY;
}
return EFI_DEVICE_ERROR;
}
/**
Invoke callbacks hooked on done TDs
@Param Entry Interrupt transfer transaction information data structure
@Param Context Ohc private data
**/
VOID
OhciInvokeInterruptCallBack(
IN INTERRUPT_CONTEXT_ENTRY *Entry,
IN UINT32 Result
)
{
//Generally speaking, Keyboard driver should not
//check the Keyboard buffer if an error happens, it will be robust
//if we NULLed the buffer once error happens
if (Result) {
Entry->CallBackFunction (
NULL,
0,
Entry->Context,
Result
);
}else{
Entry->CallBackFunction (
(VOID *)(UINTN)(Entry->DataTd->DataBuffer),
Entry->DataTd->ActualSendLength,
Entry->Context,
Result
);
}
}
/**
Timer to submit periodic interrupt transfer, and invoke callbacks hooked on done TDs
@param Event Event handle
@param Context Device private data
**/
VOID
EFIAPI
OhciHouseKeeper (
IN EFI_EVENT Event,
IN VOID *Context
)
{
USB_OHCI_HC_DEV *Ohc;
INTERRUPT_CONTEXT_ENTRY *Entry;
INTERRUPT_CONTEXT_ENTRY *PreEntry;
ED_DESCRIPTOR *Ed;
TD_DESCRIPTOR *DataTd;
TD_DESCRIPTOR *HeadTd;
UINT8 Toggle;
EFI_TPL OriginalTPL;
UINT32 Result;
Ohc = (USB_OHCI_HC_DEV *) Context;
OriginalTPL = gBS->RaiseTPL(TPL_NOTIFY);
Entry = Ohc->InterruptContextList;
PreEntry = NULL;
while(Entry != NULL) {
OhciCheckTDsResults(Ohc, Entry->DataTd, &Result );
if (((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) ||
((Result & EFI_USB_ERR_NOTEXECUTE) == EFI_USB_ERR_NOTEXECUTE)) {
PreEntry = Entry;
Entry = Entry->NextEntry;
continue;
}
if (Entry->CallBackFunction != NULL) {
OhciInvokeInterruptCallBack (Entry, Result);
if (Ohc->InterruptContextList == NULL) {
gBS->RestoreTPL (OriginalTPL);
return;
}
}
if (Entry->IsPeriodic) {
Ed = Entry->Ed;
HeadTd = Entry->DataTd;
DataTd = HeadTd;
Toggle = 0;
if (Result == EFI_USB_NOERROR) {
//
// Update toggle if there is no error, and re-submit the interrupt Ed&Tds
//
if ((Ed != NULL) && (DataTd != NULL)) {
Ed->Word0.Skip = 1;
}
//
// From hcir1_0a.pdf 4.2.2
// ToggleCarry:This bit is the data toggle carry bit,
// Whenever a TD is retired, this bit is written to
// contain the last data toggle value(LSb of data Toggel
// file) from the retired TD.
// This field is not used for Isochronous Endpoints
//
if (Ed == NULL) {
return;
}
Toggle = (UINT8) OhciGetEDField (Ed, ED_DTTOGGLE);
while(DataTd != NULL) {
if (DataTd->NextTDPointer == 0) {
DataTd->Word0.DataToggle = 0;
break;
} else {
OhciSetTDField (DataTd, TD_DT_TOGGLE, Toggle);
}
DataTd = (TD_DESCRIPTOR *)(UINTN)(DataTd->NextTDPointer);
Toggle ^= 1;
}
//
// HC will only update DataToggle, ErrorCount, ConditionCode
// CurrentBufferPointer & NextTD, so we only need to update
// them once we want to active them again
//
DataTd = HeadTd;
while (DataTd != NULL) {
if (DataTd->NextTDPointer == 0) {
OhciSetTDField (DataTd, TD_ERROR_CNT | TD_COND_CODE | TD_CURR_BUFFER_PTR | TD_NEXT_PTR, 0);
break;
}
OhciSetTDField (DataTd, TD_ERROR_CNT, 0);
OhciSetTDField (DataTd, TD_COND_CODE, TD_TOBE_PROCESSED);
DataTd->NextTD = DataTd->NextTDPointer;
DataTd->CurrBufferPointer = DataTd->DataBuffer;
DataTd = (TD_DESCRIPTOR *)(UINTN)(DataTd->NextTDPointer);
}
//
// Active current Ed,Td
//
// HC will only update Halted, ToggleCarry & TDQueueHeadPointer,
// So we only need to update them once we want to active them again.
//
if ((Ed != NULL) && (DataTd != NULL)) {
Ed->Word2.TdHeadPointer = (UINT32)((UINTN)HeadTd>>4);
OhciSetEDField (Ed, ED_HALTED | ED_DTTOGGLE, 0);
Ed->Word0.Skip = 0;
}
}
} else {
if (PreEntry == NULL) {
Ohc->InterruptContextList = Entry->NextEntry;
} else {
PreEntry = Entry;
PreEntry->NextEntry = Entry->NextEntry;
}
OhciFreeInterruptContextEntry (Ohc, PreEntry);
gBS->RestoreTPL (OriginalTPL);
return;
}
PreEntry = Entry;
Entry = Entry->NextEntry;
}
gBS->RestoreTPL (OriginalTPL);
}

View File

@@ -0,0 +1,231 @@
/** @file
This file contains the definination for host controller schedule routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _OHCI_SCHED_H
#define _OHCI_SCHED_H
#include "Descriptor.h"
#define HCCA_MEM_SIZE 256
#define GRID_SIZE 16
#define GRID_SHIFT 4
typedef struct _INTERRUPT_CONTEXT_ENTRY INTERRUPT_CONTEXT_ENTRY;
struct _INTERRUPT_CONTEXT_ENTRY{
UINT8 DeviceAddress;
UINT8 EndPointAddress;
ED_DESCRIPTOR *Ed;
TD_DESCRIPTOR *DataTd;
BOOLEAN IsSlowDevice;
UINT8 MaxPacketLength;
UINTN PollingInterval;
EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction;
VOID *Context;
BOOLEAN IsPeriodic;
VOID *Buffer;
UINTN DataLength;
VOID *UCBuffer;
VOID *UCBufferMapping;
UINT8 *Toggle;
INTERRUPT_CONTEXT_ENTRY *NextEntry;
};
typedef struct {
UINT32 ErrorCode;
UINT8 NextToggle;
} OHCI_ED_RESULT;
/**
Add an item of interrupt context
@param Ohc UHC private data
@param NewEntry New entry to add
@retval EFI_SUCCESS Item successfully added
**/
EFI_STATUS
OhciAddInterruptContextEntry (
IN USB_OHCI_HC_DEV *Ohc,
IN INTERRUPT_CONTEXT_ENTRY *NewEntry
);
/**
Free a interrupt context entry
@param Ohc UHC private data
@param Entry Pointer to an interrupt context entry
@retval EFI_SUCCESS Entry freed
@retval EFI_INVALID_PARAMETER Entry is NULL
**/
EFI_STATUS
OhciFreeInterruptContextEntry (
IN USB_OHCI_HC_DEV *Ohc,
IN INTERRUPT_CONTEXT_ENTRY *Entry
);
/**
Free entries match the device address and endpoint address
@Param Ohc UHC private date
@Param DeviceAddress Item to free must match this device address
@Param EndPointAddress Item to free must match this end point address
@Param DataToggle DataToggle for output
@retval EFI_SUCCESS Items match the requirement removed
**/
EFI_STATUS
OhciFreeInterruptContext(
IN USB_OHCI_HC_DEV *Ohc,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
OUT UINT8 *DataToggle
);
/**
Convert Error code from OHCI format to EFI format
@Param ErrorCode ErrorCode in OHCI format
@retval ErrorCode in EFI format
**/
UINT32
ConvertErrorCode (
IN UINT32 ErrorCode
);
/**
Check TDs Results
@Param Ohc UHC private data
@Param Td TD_DESCRIPTOR
@Param Result Result to return
@retval TRUE means OK
@retval FLASE means Error or Short packet
**/
BOOLEAN
OhciCheckTDsResults (
IN USB_OHCI_HC_DEV *Ohc,
IN TD_DESCRIPTOR *Td,
OUT UINT32 *Result
);
/**
Check the task status on an ED
@Param Ed Pointer to the ED task that TD hooked on
@Param HeadTd TD header for current transaction
@retval Task Status Code
**/
UINT32
CheckEDStatus (
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd,
OUT OHCI_ED_RESULT *EdResult
);
/**
Check the task status
@Param Ohc UHC private data
@Param ListType Pipe type
@Param Ed Pointer to the ED task hooked on
@Param HeadTd Head of TD corresponding to the task
@Param ErrorCode return the ErrorCode
@retval EFI_SUCCESS Task done
@retval EFI_NOT_READY Task on processing
@retval EFI_DEVICE_ERROR Some error occured
**/
EFI_STATUS
CheckIfDone (
IN USB_OHCI_HC_DEV *Ohc,
IN DESCRIPTOR_LIST_TYPE ListType,
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd,
OUT OHCI_ED_RESULT *EdResult
);
/**
Convert TD condition code to Efi Status
@Param ConditionCode Condition code to convert
@retval EFI_SUCCESS No error occured
@retval EFI_NOT_READY TD still on processing
@retval EFI_DEVICE_ERROR Error occured in processing TD
**/
EFI_STATUS
OhciTDConditionCodeToStatus (
IN UINT32 ConditionCode
);
/**
Invoke callbacks hooked on done TDs
@Param Entry Interrupt transfer transaction information data structure
@Param Context Ohc private data
**/
VOID
OhciInvokeInterruptCallBack(
IN INTERRUPT_CONTEXT_ENTRY *Entry,
IN UINT32 Result
);
/**
Timer to submit periodic interrupt transfer, and invoke callbacks hooked on done TDs
@param Event Event handle
@param Context Device private data
**/
VOID
EFIAPI
OhciHouseKeeper (
IN EFI_EVENT Event,
IN VOID *Context
);
#endif

View File

@@ -0,0 +1,895 @@
/** @file
This file contains URB request, each request is warpped in a
URB (Usb Request Block).
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Ohci.h"
/**
Create a TD
@Param Ohc UHC private data
@retval TD structure pointer
**/
TD_DESCRIPTOR *
OhciCreateTD (
IN USB_OHCI_HC_DEV *Ohc
)
{
TD_DESCRIPTOR *Td;
Td = UsbHcAllocateMem(Ohc->MemPool, sizeof(TD_DESCRIPTOR));
if (Td == NULL) {
DEBUG ((EFI_D_INFO, "STV allocate TD fail !\r\n"));
return NULL;
}
Td->CurrBufferPointer = 0;
Td->NextTD = 0;
Td->BufferEndPointer = 0;
Td->NextTDPointer = 0;
return Td;
}
/**
Free a TD
@Param Ohc UHC private data
@Param Td Pointer to a TD to free
@retval EFI_SUCCESS TD freed
**/
EFI_STATUS
OhciFreeTD (
IN USB_OHCI_HC_DEV *Ohc,
IN TD_DESCRIPTOR *Td
)
{
if (Td == NULL) {
return EFI_SUCCESS;
}
UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));
return EFI_SUCCESS;
}
/**
Create a ED
@Param Ohc Device private data
@retval ED descriptor pointer
**/
ED_DESCRIPTOR *
OhciCreateED (
USB_OHCI_HC_DEV *Ohc
)
{
ED_DESCRIPTOR *Ed;
Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));
if (Ed == NULL) {
DEBUG ((EFI_D_INFO, "STV allocate ED fail !\r\n"));
return NULL;
}
Ed->Word0.Skip = 1;
Ed->TdTailPointer = 0;
Ed->Word2.TdHeadPointer = 0;
Ed->NextED = 0;
return Ed;
}
/**
Free a ED
@Param Ohc UHC private data
@Param Ed Pointer to a ED to free
@retval EFI_SUCCESS ED freed
**/
EFI_STATUS
OhciFreeED (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *Ed
)
{
if (Ed == NULL) {
return EFI_SUCCESS;
}
UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
return EFI_SUCCESS;
}
/**
Free ED
@Param Ohc Device private data
@Param Ed Pointer to a ED to free
@retval EFI_SUCCESS ED freed
**/
EFI_STATUS
OhciFreeAllTDFromED (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *Ed
)
{
TD_DESCRIPTOR *HeadTd;
TD_DESCRIPTOR *TailTd;
TD_DESCRIPTOR *Td;
TD_DESCRIPTOR *TempTd;
if (Ed == NULL) {
return EFI_SUCCESS;
}
HeadTd = TD_PTR (Ed->Word2.TdHeadPointer);
TailTd = (TD_DESCRIPTOR *)(UINTN)(Ed->TdTailPointer);
Td = HeadTd;
while (Td != TailTd) {
TempTd = Td;
Td = (TD_DESCRIPTOR *)(UINTN)(Td->NextTDPointer);
OhciFreeTD (Ohc, TempTd);
}
return EFI_SUCCESS;
}
/**
Find a working ED match the requirement
@Param EdHead Head of the ED list
@Param DeviceAddress Device address to search
@Param EndPointNum End point num to search
@Param EdDir ED Direction to search
@retval ED descriptor searched
**/
ED_DESCRIPTOR *
OhciFindWorkingEd (
IN ED_DESCRIPTOR *EdHead,
IN UINT8 DeviceAddress,
IN UINT8 EndPointNum,
IN UINT8 EdDir
)
{
ED_DESCRIPTOR *Ed;
for (Ed = EdHead; Ed != NULL; Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED)) {
if (Ed->Word2.Halted == 0 && Ed->Word0.Skip == 0 &&
Ed->Word0.FunctionAddress == DeviceAddress && Ed->Word0.EndPointNum == EndPointNum &&
Ed->Word0.Direction == EdDir) {
break;
}
}
return Ed;
}
/**
Initialize interrupt list.
@Param Ohc Device private data
@retval EFI_SUCCESS Initialization done
**/
EFI_STATUS
OhciInitializeInterruptList (
USB_OHCI_HC_DEV *Ohc
)
{
static UINT32 Leaf[32] = {0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30, 1, 17,
9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31};
UINT32 *HccaInterruptTable;
UINTN Index;
UINTN Level;
UINTN Count;
ED_DESCRIPTOR *NewEd;
HccaInterruptTable = Ohc->HccaMemoryBlock->HccaInterruptTable;
for (Index = 0; Index < 32; Index++) {
NewEd = OhciCreateED (Ohc);
if (NewEd == NULL) {
return EFI_OUT_OF_RESOURCES;
}
HccaInterruptTable[Index] = (UINT32)(UINTN)NewEd;
}
for (Index = 0; Index < 32; Index++) {
Ohc->IntervalList[0][Index] = (ED_DESCRIPTOR *)(UINTN)HccaInterruptTable[Leaf[Index]];
}
Count = 32;
for (Level = 1; Level <= 5; Level++) {
Count = Count >> 1;
for (Index = 0; Index < Count; Index++) {
Ohc->IntervalList[Level][Index] = OhciCreateED (Ohc);
if (HccaInterruptTable[Index] == 0) {
return EFI_OUT_OF_RESOURCES;
}
Ohc->IntervalList[Level - 1][Index * 2 ]->NextED = (UINT32)(UINTN)Ohc->IntervalList[Level][Index];
Ohc->IntervalList[Level - 1][Index * 2 + 1]->NextED = (UINT32)(UINTN)Ohc->IntervalList[Level][Index];
}
}
return EFI_SUCCESS;
}
/**
Attach an ED
@Param Ed Ed to be attached
@Param NewEd Ed to attach
@retval EFI_SUCCESS NewEd attached to Ed
@retval EFI_INVALID_PARAMETER Ed is NULL
**/
EFI_STATUS
OhciAttachED (
IN ED_DESCRIPTOR *Ed,
IN ED_DESCRIPTOR *NewEd
)
{
ED_DESCRIPTOR *Temp;
if (Ed == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Ed->NextED == 0){
Ed->NextED = (UINT32)(UINTN)NewEd;
} else {
Temp = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
Ed->NextED = (UINT32)(UINTN)NewEd;
NewEd->NextED = (UINT32)(UINTN)Temp;
}
return EFI_SUCCESS;
}
/**
Count ED number on a ED chain
@Param Ed Head of the ED chain
@retval ED number on the chain
**/
UINTN
CountEdNum (
IN ED_DESCRIPTOR *Ed
)
{
UINTN Count;
Count = 0;
while (Ed) {
Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
Count++;
}
return Count;
}
/**
Find the minimal burn ED list on a specific depth level
@Param Ohc Device private data
@Param Depth Depth level
@retval ED list found
**/
ED_DESCRIPTOR *
OhciFindMinInterruptEDList (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Depth
)
{
UINTN EdNum;
UINTN MinEdNum;
ED_DESCRIPTOR *TempEd;
ED_DESCRIPTOR *HeadEd;
UINTN Index;
if (Depth > 5) {
return NULL;
}
MinEdNum = 0xFFFFFFFF;
TempEd = NULL;
for (Index = 0; Index < (UINTN)(32 >> Depth); Index++) {
HeadEd = Ohc->IntervalList[Depth][Index];
EdNum = CountEdNum (HeadEd);
if (EdNum < MinEdNum) {
MinEdNum = EdNum;
TempEd = HeadEd;
}
}
ASSERT (TempEd != NULL);
return TempEd;
}
/**
Attach an ED to an ED list
@Param OHC UHC private data
@Param ListType Type of the ED list
@Param Ed ED to attach
@Param EdList ED list to be attached
@retval EFI_SUCCESS ED attached to ED list
**/
ED_DESCRIPTOR *
OhciAttachEDToList (
IN USB_OHCI_HC_DEV *Ohc,
IN DESCRIPTOR_LIST_TYPE ListType,
IN ED_DESCRIPTOR *Ed,
IN ED_DESCRIPTOR *EdList
)
{
ED_DESCRIPTOR *HeadEd;
HeadEd = NULL;
switch(ListType) {
case CONTROL_LIST:
HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_CONTROL_HEAD);
if (HeadEd == NULL) {
OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, Ed);
HeadEd = Ed;
} else {
OhciAttachED (HeadEd, Ed);
}
break;
case BULK_LIST:
HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_BULK_HEAD);
if (HeadEd == NULL) {
OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, Ed);
HeadEd = Ed;
} else {
OhciAttachED (HeadEd, Ed);
}
break;
case INTERRUPT_LIST:
OhciAttachED (EdList, Ed);
break;
default:
ASSERT (FALSE);
}
return HeadEd;
}
/**
Remove interrupt EDs that match requirement
@Param Ohc UHC private data
@Param IntEd The address of Interrupt endpoint
@retval EFI_SUCCESS EDs match requirement removed
**/
EFI_STATUS
OhciFreeInterruptEdByEd (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *IntEd
)
{
ED_DESCRIPTOR *Ed;
ED_DESCRIPTOR *TempEd;
UINTN Index;
if (IntEd == NULL)
return EFI_SUCCESS;
for (Index = 0; Index < 32; Index++) {
Ed = (ED_DESCRIPTOR *)(UINTN)Ohc->HccaMemoryBlock->HccaInterruptTable[Index];
if (Ed == NULL) {
continue;
}
while (Ed->NextED != 0) {
if (Ed->NextED == (UINT32)(UINTN)IntEd ) {
TempEd = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
Ed->NextED = TempEd->NextED;
OhciFreeED (Ohc, TempEd);
} else {
Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
}
}
}
return EFI_SUCCESS;
}
/**
Remove interrupt EDs that match requirement
@Param Ohc UHC private data
@Param FunctionAddress Requirement on function address
@Param EndPointNum Requirement on end point number
@retval EFI_SUCCESS EDs match requirement removed
**/
EFI_STATUS
OhciFreeInterruptEdByAddr (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT8 FunctionAddress,
IN UINT8 EndPointNum
)
{
ED_DESCRIPTOR *Ed;
ED_DESCRIPTOR *TempEd;
UINTN Index;
for (Index = 0; Index < 32; Index++) {
Ed = (ED_DESCRIPTOR *)(UINTN)Ohc->HccaMemoryBlock->HccaInterruptTable[Index];
if (Ed == NULL) {
continue;
}
while (Ed->NextED != 0) {
TempEd = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
if (TempEd->Word0.FunctionAddress == FunctionAddress &&
TempEd->Word0.EndPointNum == EndPointNum ) {
Ed->NextED = TempEd->NextED;
OhciFreeED (Ohc, TempEd);
} else {
Ed = (ED_DESCRIPTOR *)(UINTN)(Ed->NextED);
}
}
}
return EFI_SUCCESS;
}
/**
Link Td2 to the end of Td1
@Param Td1 TD to be linked
@Param Td2 TD to link
@retval EFI_SUCCESS TD successfully linked
@retval EFI_INVALID_PARAMETER Td1 is NULL
**/
EFI_STATUS
OhciLinkTD (
IN TD_DESCRIPTOR *Td1,
IN TD_DESCRIPTOR *Td2
)
{
TD_DESCRIPTOR *TempTd;
if (Td1 == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Td1 == Td2) {
return EFI_SUCCESS;
}
TempTd = Td1;
while (TempTd->NextTD != 0) {
TempTd = (TD_DESCRIPTOR *)(UINTN)(TempTd->NextTD);
}
TempTd->NextTD = (UINT32)(UINTN)Td2;
TempTd->NextTDPointer = (UINT32)(UINTN)Td2;
return EFI_SUCCESS;
}
/**
Attach TD list to ED
@Param Ed ED which TD list attach on
@Param HeadTd Head of the TD list to attach
@retval EFI_SUCCESS TD list attached on the ED
**/
EFI_STATUS
OhciAttachTDListToED (
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd
)
{
TD_DESCRIPTOR *TempTd;
TempTd = TD_PTR (Ed->Word2.TdHeadPointer);
if (TempTd != NULL) {
while (TempTd->NextTD != 0) {
TempTd = (TD_DESCRIPTOR *)(UINTN)(TempTd->NextTD);
}
TempTd->NextTD = (UINT32)(UINTN)HeadTd;
TempTd->NextTDPointer = (UINT32)(UINTN)HeadTd;
} else {
Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32)(UINTN)HeadTd);
}
return EFI_SUCCESS;
}
/**
Set value to ED specific field
@Param Ed ED to be set
@Param Field Field to be set
@Param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetEDField (
IN ED_DESCRIPTOR *Ed,
IN UINT32 Field,
IN UINT32 Value
)
{
if (Field & ED_FUNC_ADD) {
Ed->Word0.FunctionAddress = Value;
}
if (Field & ED_ENDPT_NUM) {
Ed->Word0.EndPointNum = Value;
}
if (Field & ED_DIR) {
Ed->Word0.Direction = Value;
}
if (Field & ED_SPEED) {
Ed->Word0.Speed = Value;
}
if (Field & ED_SKIP) {
Ed->Word0.Skip = Value;
}
if (Field & ED_FORMAT) {
Ed->Word0.Format = Value;
}
if (Field & ED_MAX_PACKET) {
Ed->Word0.MaxPacketSize = Value;
}
if (Field & ED_PDATA) {
Ed->Word0.FreeSpace = Value;
}
if (Field & ED_ZERO) {
Ed->Word2.Zero = Value;
}
if (Field & ED_TDTAIL_PTR) {
Ed->TdTailPointer = Value;
}
if (Field & ED_HALTED) {
Ed->Word2.Halted = Value;
}
if (Field & ED_DTTOGGLE) {
Ed->Word2.ToggleCarry = Value;
}
if (Field & ED_TDHEAD_PTR) {
Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 (Value);
}
if (Field & ED_NEXT_EDPTR) {
Ed->NextED = Value;
}
return EFI_SUCCESS;
}
/**
Get value from an ED's specific field
@Param Ed ED pointer
@Param Field Field to get value from
@retval Value of the field
**/
UINT32
OhciGetEDField (
IN ED_DESCRIPTOR *Ed,
IN UINT32 Field
)
{
switch (Field) {
case ED_FUNC_ADD:
return Ed->Word0.FunctionAddress;
break;
case ED_ENDPT_NUM:
return Ed->Word0.EndPointNum;
break;
case ED_DIR:
return Ed->Word0.Direction;
break;
case ED_SPEED:
return Ed->Word0.Speed;
break;
case ED_SKIP:
return Ed->Word0.Skip;
break;
case ED_FORMAT:
return Ed->Word0.Format;
break;
case ED_MAX_PACKET:
return Ed->Word0.MaxPacketSize;
break;
case ED_TDTAIL_PTR:
return Ed->TdTailPointer;
break;
case ED_HALTED:
return Ed->Word2.Halted;
break;
case ED_DTTOGGLE:
return Ed->Word2.ToggleCarry;
break;
case ED_TDHEAD_PTR:
return Ed->Word2.TdHeadPointer << 4;
break;
case ED_NEXT_EDPTR:
return Ed->NextED;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set value to TD specific field
@Param Td TD to be set
@Param Field Field to be set
@Param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetTDField (
IN TD_DESCRIPTOR *Td,
IN UINT32 Field,
IN UINT32 Value
)
{
if (Field & TD_PDATA) {
Td->Word0.Reserved = Value;
}
if (Field & TD_BUFFER_ROUND) {
Td->Word0.BufferRounding = Value;
}
if (Field & TD_DIR_PID) {
Td->Word0.DirPID = Value;
}
if (Field & TD_DELAY_INT) {
Td->Word0.DelayInterrupt = Value;
}
if (Field & TD_DT_TOGGLE) {
Td->Word0.DataToggle = Value | 0x2;
}
if (Field & TD_ERROR_CNT) {
Td->Word0.ErrorCount = Value;
}
if (Field & TD_COND_CODE) {
Td->Word0.ConditionCode = Value;
}
if (Field & TD_CURR_BUFFER_PTR) {
Td->CurrBufferPointer = Value;
}
if (Field & TD_NEXT_PTR) {
Td->NextTD = Value;
}
if (Field & TD_BUFFER_END_PTR) {
Td->BufferEndPointer = Value;
}
return EFI_SUCCESS;
}
/**
Get value from ED specific field
@Param Td TD pointer
@Param Field Field to get value from
@retval Value of the field
**/
UINT32
OhciGetTDField (
IN TD_DESCRIPTOR *Td,
IN UINT32 Field
)
{
switch (Field){
case TD_BUFFER_ROUND:
return Td->Word0.BufferRounding;
break;
case TD_DIR_PID:
return Td->Word0.DirPID;
break;
case TD_DELAY_INT:
return Td->Word0.DelayInterrupt;
break;
case TD_DT_TOGGLE:
return Td->Word0.DataToggle;
break;
case TD_ERROR_CNT:
return Td->Word0.ErrorCount;
break;
case TD_COND_CODE:
return Td->Word0.ConditionCode;
break;
case TD_CURR_BUFFER_PTR:
return Td->CurrBufferPointer;
break;
case TD_NEXT_PTR:
return Td->NextTD;
break;
case TD_BUFFER_END_PTR:
return Td->BufferEndPointer;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Free the Ed,Td,buffer that were created during transferring
@Param Ohc Device private data
**/
VOID
OhciFreeDynamicIntMemory(
IN USB_OHCI_HC_DEV *Ohc
)
{
INTERRUPT_CONTEXT_ENTRY *Entry;
if (Ohc != NULL) {
while (Ohc->InterruptContextList != NULL) {
Entry = Ohc->InterruptContextList;
Ohc->InterruptContextList = Ohc->InterruptContextList->NextEntry;
OhciFreeInterruptEdByEd (Ohc, Entry->Ed);
OhciFreeInterruptContextEntry (Ohc, Entry);
}
}
}
/**
Free the Ed that were initilized during driver was starting,
those memory were used as interrupt ED head
@Param Ohc Device private data
**/
VOID
OhciFreeFixedIntMemory (
IN USB_OHCI_HC_DEV *Ohc
)
{
static UINT32 Leaf[] = {32,16,8,4,2,1};
UINTN Index;
UINTN Level;
for (Level = 0; Level < 6; Level++) {
for (Index = 0; Index < Leaf[Level]; Index++) {
if (Ohc->IntervalList[Level][Index] != NULL) {
UsbHcFreeMem(Ohc->MemPool, Ohc->IntervalList[Level][Index], sizeof(ED_DESCRIPTOR));
}
}
}
}
/**
Release all OHCI used memory when OHCI going to quit
@Param Ohc Device private data
@retval EFI_SUCCESS Memory released
**/
EFI_STATUS
OhciFreeIntTransferMemory (
IN USB_OHCI_HC_DEV *Ohc
)
{
//
// Free the Ed,Td,buffer that were created during transferring
//
OhciFreeDynamicIntMemory (Ohc);
//
// Free the Ed that were initilized during driver was starting
//
OhciFreeFixedIntMemory (Ohc);
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,393 @@
/** @file
Provides some data struct used by OHCI controller driver.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _OHCI_URB_H
#define _OHCI_URB_H
#include "Descriptor.h"
//
// Func List
//
/**
Create a TD
@Param Ohc UHC private data
@retval TD structure pointer
**/
TD_DESCRIPTOR *
OhciCreateTD (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Free a TD
@Param Ohc UHC private data
@Param Td Pointer to a TD to free
@retval EFI_SUCCESS TD freed
**/
EFI_STATUS
OhciFreeTD (
IN USB_OHCI_HC_DEV *Ohc,
IN TD_DESCRIPTOR *Td
);
/**
Create a ED
@Param Ohc Device private data
@retval ED descriptor pointer
**/
ED_DESCRIPTOR *
OhciCreateED (
USB_OHCI_HC_DEV *Ohc
);
/**
Free a ED
@Param Ohc UHC private data
@Param Ed Pointer to a ED to free
@retval EFI_SUCCESS ED freed
**/
EFI_STATUS
OhciFreeED (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *Ed
);
/**
Free ED
@Param Ohc Device private data
@Param Ed Pointer to a ED to free
@retval EFI_SUCCESS ED freed
**/
EFI_STATUS
OhciFreeAllTDFromED (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *Ed
);
/**
Find a working ED match the requirement
@Param EdHead Head of the ED list
@Param DeviceAddress Device address to search
@Param EndPointNum End point num to search
@Param EdDir ED Direction to search
@retval ED descriptor searched
**/
ED_DESCRIPTOR *
OhciFindWorkingEd (
IN ED_DESCRIPTOR *EdHead,
IN UINT8 DeviceAddress,
IN UINT8 EndPointNum,
IN UINT8 EdDir
);
/**
Initialize interrupt list.
@Param Ohc Device private data
@retval EFI_SUCCESS Initialization done
**/
EFI_STATUS
OhciInitializeInterruptList (
USB_OHCI_HC_DEV *Ohc
);
/**
Attach an ED
@Param Ed Ed to be attached
@Param NewEd Ed to attach
@retval EFI_SUCCESS NewEd attached to Ed
@retval EFI_INVALID_PARAMETER Ed is NULL
**/
EFI_STATUS
OhciAttachED (
IN ED_DESCRIPTOR *Ed,
IN ED_DESCRIPTOR *NewEd
);
/**
Count ED number on a ED chain
@Param Ed Head of the ED chain
@retval ED number on the chain
**/
UINTN
CountEdNum (
IN ED_DESCRIPTOR *Ed
);
/**
Find the minimal burn ED list on a specific depth level
@Param Ohc Device private data
@Param Depth Depth level
@retval ED list found
**/
ED_DESCRIPTOR *
OhciFindMinInterruptEDList (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Depth
);
/**
Attach an ED to an ED list
@Param OHC UHC private data
@Param ListType Type of the ED list
@Param Ed ED to attach
@Param EdList ED list to be attached
@retval EFI_SUCCESS ED attached to ED list
**/
ED_DESCRIPTOR *
OhciAttachEDToList (
IN USB_OHCI_HC_DEV *Ohc,
IN DESCRIPTOR_LIST_TYPE ListType,
IN ED_DESCRIPTOR *Ed,
IN ED_DESCRIPTOR *EdList
);
/**
Remove interrupt EDs that match requirement
@Param Ohc UHC private data
@Param IntEd The address of Interrupt endpoint
@retval EFI_SUCCESS EDs match requirement removed
**/
EFI_STATUS
OhciFreeInterruptEdByEd (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *IntEd
);
/**
Remove interrupt EDs that match requirement
@Param Ohc UHC private data
@Param FunctionAddress Requirement on function address
@Param EndPointNum Requirement on end point number
@retval EFI_SUCCESS EDs match requirement removed
**/
EFI_STATUS
OhciFreeInterruptEdByAddr (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT8 FunctionAddress,
IN UINT8 EndPointNum
);
/**
Link Td2 to the end of Td1
@Param Td1 TD to be linked
@Param Td2 TD to link
@retval EFI_SUCCESS TD successfully linked
@retval EFI_INVALID_PARAMETER Td1 is NULL
**/
EFI_STATUS
OhciLinkTD (
IN TD_DESCRIPTOR *Td1,
IN TD_DESCRIPTOR *Td2
);
/**
Attach TD list to ED
@Param Ed ED which TD list attach on
@Param HeadTd Head of the TD list to attach
@retval EFI_SUCCESS TD list attached on the ED
**/
EFI_STATUS
OhciAttachTDListToED (
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd
);
/**
Set value to ED specific field
@Param Ed ED to be set
@Param Field Field to be set
@Param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetEDField (
IN ED_DESCRIPTOR *Ed,
IN UINT32 Field,
IN UINT32 Value
);
/**
Get value from an ED's specific field
@Param Ed ED pointer
@Param Field Field to get value from
@retval Value of the field
**/
UINT32
OhciGetEDField (
IN ED_DESCRIPTOR *Ed,
IN UINT32 Field
);
/**
Set value to TD specific field
@Param Td TD to be set
@Param Field Field to be set
@Param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetTDField (
IN TD_DESCRIPTOR *Td,
IN UINT32 Field,
IN UINT32 Value
);
/**
Get value from ED specific field
@Param Td TD pointer
@Param Field Field to get value from
@retval Value of the field
**/
UINT32
OhciGetTDField (
IN TD_DESCRIPTOR *Td,
IN UINT32 Field
);
/**
Free the Ed,Td,buffer that were created during transferring
@Param Ohc Device private data
**/
VOID
OhciFreeDynamicIntMemory(
IN USB_OHCI_HC_DEV *Ohc
);
/**
Free the Ed that were initilized during driver was starting,
those memory were used as interrupt ED head
@Param Ohc Device private data
**/
VOID
OhciFreeFixedIntMemory (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Release all OHCI used memory when OHCI going to quit
@Param Ohc Device private data
@retval EFI_SUCCESS Memory released
**/
EFI_STATUS
OhciFreeIntTransferMemory (
IN USB_OHCI_HC_DEV *Ohc
);
#endif

View File

@@ -0,0 +1,566 @@
/** @file
Routine procedures for memory allocate/free.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Ohci.h"
/**
Allocate a block of memory to be used by the buffer pool.
@param Pool The buffer pool to allocate memory for.
@param Pages How many pages to allocate.
@return The allocated memory block or NULL if failed.
**/
USBHC_MEM_BLOCK *
UsbHcAllocMemBlock (
IN USBHC_MEM_POOL *Pool,
IN UINTN Pages
)
{
USBHC_MEM_BLOCK *Block;
EFI_PCI_IO_PROTOCOL *PciIo;
VOID *BufHost;
VOID *Mapping;
EFI_PHYSICAL_ADDRESS MappedAddr;
UINTN Bytes;
EFI_STATUS Status;
PciIo = Pool->PciIo;
Block = AllocateZeroPool (sizeof (USBHC_MEM_BLOCK));
if (Block == NULL) {
return NULL;
}
//
// each bit in the bit array represents USBHC_MEM_UNIT
// bytes of memory in the memory block.
//
ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);
Block->BufLen = EFI_PAGES_TO_SIZE (Pages);
Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8);
Block->Bits = AllocateZeroPool (Block->BitsLen);
if (Block->Bits == NULL) {
gBS->FreePool (Block);
return NULL;
}
//
// Allocate the number of Pages of memory, then map it for
// bus master read and write.
//
Status = PciIo->AllocateBuffer (
PciIo,
AllocateAnyPages,
EfiBootServicesData,
Pages,
&BufHost,
0
);
if (EFI_ERROR (Status)) {
goto FREE_BITARRAY;
}
Bytes = EFI_PAGES_TO_SIZE (Pages);
Status = PciIo->Map (
PciIo,
EfiPciIoOperationBusMasterCommonBuffer,
BufHost,
&Bytes,
&MappedAddr,
&Mapping
);
if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) {
goto FREE_BUFFER;
}
//
// Check whether the data structure used by the host controller
// should be restricted into the same 4G
//
if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) {
PciIo->Unmap (PciIo, Mapping);
goto FREE_BUFFER;
}
Block->BufHost = BufHost;
Block->Buf = (UINT8 *) ((UINTN) MappedAddr);
Block->Mapping = Mapping;
return Block;
FREE_BUFFER:
PciIo->FreeBuffer (PciIo, Pages, BufHost);
FREE_BITARRAY:
gBS->FreePool (Block->Bits);
gBS->FreePool (Block);
return NULL;
}
/**
Free the memory block from the memory pool.
@param Pool The memory pool to free the block from.
@param Block The memory block to free.
**/
VOID
UsbHcFreeMemBlock (
IN USBHC_MEM_POOL *Pool,
IN USBHC_MEM_BLOCK *Block
)
{
EFI_PCI_IO_PROTOCOL *PciIo;
ASSERT ((Pool != NULL) && (Block != NULL));
PciIo = Pool->PciIo;
//
// Unmap the common buffer then free the structures
//
PciIo->Unmap (PciIo, Block->Mapping);
PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost);
gBS->FreePool (Block->Bits);
gBS->FreePool (Block);
}
/**
Alloc some memory from the block.
@param Block The memory block to allocate memory from.
@param Units Number of memory units to allocate.
@return The pointer to the allocated memory. If couldn't allocate the needed memory,
the return value is NULL.
**/
VOID *
UsbHcAllocMemFromBlock (
IN USBHC_MEM_BLOCK *Block,
IN UINTN Units
)
{
UINTN Byte;
UINT8 Bit;
UINTN StartByte;
UINT8 StartBit;
UINTN Available;
UINTN Count;
ASSERT ((Block != 0) && (Units != 0));
StartByte = 0;
StartBit = 0;
Available = 0;
for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
//
// If current bit is zero, the corresponding memory unit is
// available, otherwise we need to restart our searching.
// Available counts the consective number of zero bit.
//
if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
Available++;
if (Available >= Units) {
break;
}
NEXT_BIT (Byte, Bit);
} else {
NEXT_BIT (Byte, Bit);
Available = 0;
StartByte = Byte;
StartBit = Bit;
}
}
if (Available < Units) {
return NULL;
}
//
// Mark the memory as allocated
//
Byte = StartByte;
Bit = StartBit;
for (Count = 0; Count < Units; Count++) {
ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | USB_HC_BIT (Bit));
NEXT_BIT (Byte, Bit);
}
return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
}
/**
Calculate the corresponding pci bus address according to the Mem parameter.
@param Pool The memory pool of the host controller.
@param Mem The pointer to host memory.
@param Size The size of the memory region.
@return the pci memory address
**/
EFI_PHYSICAL_ADDRESS
UsbHcGetPciAddressForHostMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
)
{
USBHC_MEM_BLOCK *Head;
USBHC_MEM_BLOCK *Block;
UINTN AllocSize;
EFI_PHYSICAL_ADDRESS PhyAddr;
UINTN Offset;
Head = Pool->Head;
AllocSize = USBHC_MEM_ROUND (Size);
if (Mem == NULL) {
return 0;
}
for (Block = Head; Block != NULL; Block = Block->Next) {
//
// scan the memory block list for the memory block that
// completely contains the allocated memory.
//
if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {
break;
}
}
ASSERT ((Block != NULL));
//
// calculate the pci memory address for host memory address.
//
Offset = (UINT8 *)Mem - Block->BufHost;
PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);
return PhyAddr;
}
/**
Insert the memory block to the pool's list of the blocks.
@param Head The head of the memory pool's block list.
@param Block The memory block to insert.
**/
VOID
UsbHcInsertMemBlockToPool (
IN USBHC_MEM_BLOCK *Head,
IN USBHC_MEM_BLOCK *Block
)
{
ASSERT ((Head != NULL) && (Block != NULL));
Block->Next = Head->Next;
Head->Next = Block;
}
/**
Is the memory block empty?
@param Block The memory block to check.
@retval TRUE The memory block is empty.
@retval FALSE The memory block isn't empty.
**/
BOOLEAN
UsbHcIsMemBlockEmpty (
IN USBHC_MEM_BLOCK *Block
)
{
UINTN Index;
for (Index = 0; Index < Block->BitsLen; Index++) {
if (Block->Bits[Index] != 0) {
return FALSE;
}
}
return TRUE;
}
/**
Unlink the memory block from the pool's list.
@param Head The block list head of the memory's pool.
@param BlockToUnlink The memory block to unlink.
**/
VOID
UsbHcUnlinkMemBlock (
IN USBHC_MEM_BLOCK *Head,
IN USBHC_MEM_BLOCK *BlockToUnlink
)
{
USBHC_MEM_BLOCK *Block;
ASSERT ((Head != NULL) && (BlockToUnlink != NULL));
for (Block = Head; Block != NULL; Block = Block->Next) {
if (Block->Next == BlockToUnlink) {
Block->Next = BlockToUnlink->Next;
BlockToUnlink->Next = NULL;
break;
}
}
}
/**
Initialize the memory management pool for the host controller.
@param PciIo The PciIo that can be used to access the host controller.
@param Check4G Whether the host controller requires allocated memory
from one 4G address space.
@param Which4G The 4G memory area each memory allocated should be from.
@retval EFI_SUCCESS The memory pool is initialized.
@retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.
**/
USBHC_MEM_POOL *
UsbHcInitMemPool (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN BOOLEAN Check4G,
IN UINT32 Which4G
)
{
USBHC_MEM_POOL *Pool;
Pool = AllocatePool (sizeof (USBHC_MEM_POOL));
if (Pool == NULL) {
return Pool;
}
Pool->PciIo = PciIo;
Pool->Check4G = Check4G;
Pool->Which4G = Which4G;
Pool->Head = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES);
if (Pool->Head == NULL) {
gBS->FreePool (Pool);
Pool = NULL;
}
return Pool;
}
/**
Release the memory management pool.
@param Pool The USB memory pool to free.
@retval EFI_SUCCESS The memory pool is freed.
@retval EFI_DEVICE_ERROR Failed to free the memory pool.
**/
EFI_STATUS
UsbHcFreeMemPool (
IN USBHC_MEM_POOL *Pool
)
{
USBHC_MEM_BLOCK *Block;
ASSERT (Pool->Head != NULL);
//
// Unlink all the memory blocks from the pool, then free them.
// UsbHcUnlinkMemBlock can't be used to unlink and free the
// first block.
//
for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
UsbHcUnlinkMemBlock (Pool->Head, Block);
UsbHcFreeMemBlock (Pool, Block);
}
UsbHcFreeMemBlock (Pool, Pool->Head);
gBS->FreePool (Pool);
return EFI_SUCCESS;
}
/**
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
@param Pool The host controller's memory pool.
@param Size Size of the memory to allocate.
@return The allocated memory or NULL.
**/
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
IN UINTN Size
)
{
USBHC_MEM_BLOCK *Head;
USBHC_MEM_BLOCK *Block;
USBHC_MEM_BLOCK *NewBlock;
VOID *Mem;
UINTN AllocSize;
UINTN Pages;
Mem = NULL;
AllocSize = USBHC_MEM_ROUND (Size);
Head = Pool->Head;
ASSERT (Head != NULL);
//
// First check whether current memory blocks can satisfy the allocation.
//
for (Block = Head; Block != NULL; Block = Block->Next) {
Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
if (Mem != NULL) {
ZeroMem (Mem, Size);
break;
}
}
if (Mem != NULL) {
return Mem;
}
//
// Create a new memory block if there is not enough memory
// in the pool. If the allocation size is larger than the
// default page number, just allocate a large enough memory
// block. Otherwise allocate default pages.
//
if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) {
Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1;
} else {
Pages = USBHC_MEM_DEFAULT_PAGES;
}
NewBlock = UsbHcAllocMemBlock (Pool, Pages);
if (NewBlock == NULL) {
DEBUG ((EFI_D_INFO, "UsbHcAllocateMem: failed to allocate block\n"));
return NULL;
}
//
// Add the new memory block to the pool, then allocate memory from it
//
UsbHcInsertMemBlockToPool (Head, NewBlock);
Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
if (Mem != NULL) {
ZeroMem (Mem, Size);
}
return Mem;
}
/**
Free the allocated memory back to the memory pool.
@param Pool The memory pool of the host controller.
@param Mem The memory to free.
@param Size The size of the memory to free.
**/
VOID
UsbHcFreeMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
)
{
USBHC_MEM_BLOCK *Head;
USBHC_MEM_BLOCK *Block;
UINT8 *ToFree;
UINTN AllocSize;
UINTN Byte;
UINTN Bit;
UINTN Count;
Head = Pool->Head;
AllocSize = USBHC_MEM_ROUND (Size);
ToFree = (UINT8 *) Mem;
for (Block = Head; Block != NULL; Block = Block->Next) {
//
// scan the memory block list for the memory block that
// completely contains the memory to free.
//
if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {
//
// compute the start byte and bit in the bit array
//
Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;
Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;
//
// reset associated bits in bit arry
//
for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {
ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit));
NEXT_BIT (Byte, Bit);
}
break;
}
}
//
// If Block == NULL, it means that the current memory isn't
// in the host controller's pool. This is critical because
// the caller has passed in a wrong memory point
//
ASSERT (Block != NULL);
//
// Release the current memory block if it is empty and not the head
//
if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
UsbHcUnlinkMemBlock (Head, Block);
UsbHcFreeMemBlock (Pool, Block);
}
return ;
}

View File

@@ -0,0 +1,158 @@
/** @file
This file contains the definination for host controller memory
management routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _USB_HC_MEM_H_
#define _USB_HC_MEM_H_
#define USB_HC_BIT(a) ((UINTN)(1 << (a)))
#define USB_HC_BIT_IS_SET(Data, Bit) \
((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit)))
#define USB_HC_HIGH_32BIT(Addr64) \
((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF))
typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK;
struct _USBHC_MEM_BLOCK {
UINT8 *Bits; // Bit array to record which unit is allocated
UINTN BitsLen;
UINT8 *Buf;
UINT8 *BufHost;
UINTN BufLen; // Memory size in bytes
VOID *Mapping;
USBHC_MEM_BLOCK *Next;
};
//
// USBHC_MEM_POOL is used to manage the memory used by USB
// host controller. EHCI requires the control memory and transfer
// data to be on the same 4G memory.
//
typedef struct _USBHC_MEM_POOL {
EFI_PCI_IO_PROTOCOL *PciIo;
BOOLEAN Check4G;
UINT32 Which4G;
USBHC_MEM_BLOCK *Head;
} USBHC_MEM_POOL;
//
// Memory allocation unit, must be 2^n, n>4
//
#define USBHC_MEM_UNIT 64
#define USBHC_MEM_UNIT_MASK (USBHC_MEM_UNIT - 1)
#define USBHC_MEM_DEFAULT_PAGES 16
#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
//
// Advance the byte and bit to the next bit, adjust byte accordingly.
//
#define NEXT_BIT(Byte, Bit) \
do { \
(Bit)++; \
if ((Bit) > 7) { \
(Byte)++; \
(Bit) = 0; \
} \
} while (0)
/**
Initialize the memory management pool for the host controller.
@param PciIo The PciIo that can be used to access the host controller.
@param Check4G Whether the host controller requires allocated memory
from one 4G address space.
@param Which4G The 4G memory area each memory allocated should be from.
@retval EFI_SUCCESS The memory pool is initialized.
@retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.
**/
USBHC_MEM_POOL *
UsbHcInitMemPool (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN BOOLEAN Check4G,
IN UINT32 Which4G
);
/**
Release the memory management pool.
@param Pool The USB memory pool to free.
@retval EFI_SUCCESS The memory pool is freed.
@retval EFI_DEVICE_ERROR Failed to free the memory pool.
**/
EFI_STATUS
UsbHcFreeMemPool (
IN USBHC_MEM_POOL *Pool
);
/**
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
@param Pool The host controller's memory pool.
@param Size Size of the memory to allocate.
@return The allocated memory or NULL.
**/
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
IN UINTN Size
);
/**
Free the allocated memory back to the memory pool.
@param Pool The memory pool of the host controller.
@param Mem The memory to free.
@param Size The size of the memory to free.
**/
VOID
UsbHcFreeMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
);
/**
Calculate the corresponding pci bus address according to the Mem parameter.
@param Pool The memory pool of the host controller.
@param Mem The pointer to host memory.
@param Size The size of the memory region.
@return the pci memory address
**/
EFI_PHYSICAL_ADDRESS
UsbHcGetPciAddressForHostMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
);
#endif

View File

@@ -0,0 +1,137 @@
/** @file
This file contains the descriptor definination of OHCI spec
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _DESCRIPTOR_H
#define _DESCRIPTOR_H
#define ED_FUNC_ADD 0x0001
#define ED_ENDPT_NUM 0x0002
#define ED_DIR 0x0004
#define ED_SPEED 0x0008
#define ED_SKIP 0x0010
#define ED_FORMAT 0x0020
#define ED_MAX_PACKET 0x0040
#define ED_TDTAIL_PTR 0x0080
#define ED_HALTED 0x0100
#define ED_DTTOGGLE 0x0200
#define ED_TDHEAD_PTR 0x0400
#define ED_NEXT_EDPTR 0x0800
#define ED_PDATA 0x1000
#define ED_ZERO 0x2000
#define TD_BUFFER_ROUND 0x0001
#define TD_DIR_PID 0x0002
#define TD_DELAY_INT 0x0004
#define TD_DT_TOGGLE 0x0008
#define TD_ERROR_CNT 0x0010
#define TD_COND_CODE 0x0020
#define TD_CURR_BUFFER_PTR 0x0040
#define TD_NEXT_PTR 0x0080
#define TD_BUFFER_END_PTR 0x0100
#define TD_PDATA 0x0200
#define ED_FROM_TD_DIR 0x0
#define ED_OUT_DIR 0x1
#define ED_IN_DIR 0x2
#define ED_FROM_TD_ALSO_DIR 0x3
#define TD_SETUP_PID 0x00
#define TD_OUT_PID 0x01
#define TD_IN_PID 0x02
#define TD_NODATA_PID 0x03
#define HI_SPEED 0
#define LO_SPEED 1
#define TD_NO_ERROR 0x00
#define TD_CRC_ERROR 0x01
#define TD_BITSTUFFING_ERROR 0x02
#define TD_TOGGLE_ERROR 0x03
#define TD_DEVICE_STALL 0x04
#define TD_NO_RESPONSE 0x05
#define TD_PIDCHK_FAIL 0x06
#define TD_PID_UNEXPECTED 0x07
#define TD_DATA_OVERRUN 0x08
#define TD_DATA_UNDERRUN 0x09
#define TD_BUFFER_OVERRUN 0x0C
#define TD_BUFFER_UNDERRUN 0x0D
#define TD_TOBE_PROCESSED 0x0E
#define TD_TOBE_PROCESSED_2 0x0F
#define TD_NO_DELAY 0x7
#define TD_INT 0x1
#define TD_CTL 0x2
#define TD_BLK 0x3
typedef struct {
UINT32 Reserved:18;
UINT32 BufferRounding:1;
UINT32 DirPID:2;
UINT32 DelayInterrupt:3;
UINT32 DataToggle:2;
UINT32 ErrorCount:2;
UINT32 ConditionCode:4;
} TD_DESCRIPTOR_WORD0;
typedef struct _TD_DESCRIPTOR {
TD_DESCRIPTOR_WORD0 Word0;
VOID *CurrBufferPointer;
struct _TD_DESCRIPTOR *NextTD;
VOID *BufferEndPointer;
struct _TD_DESCRIPTOR *NextTDPointer;
UINT8 *DataBuffer;
UINT32 ActualSendLength;
} TD_DESCRIPTOR;
typedef struct {
UINT32 FunctionAddress:7;
UINT32 EndPointNum:4;
UINT32 Direction:2;
UINT32 Speed:1;
UINT32 Skip:1;
UINT32 Format:1;
UINT32 MaxPacketSize:11;
UINT32 FreeSpace:5;
} ED_DESCRIPTOR_WORD0;
typedef struct {
UINT32 Halted:1;
UINT32 ToggleCarry:1;
UINT32 Zero:2;
UINT32 TdHeadPointer:28;
} ED_DESCRIPTOR_WORD2;
typedef struct _ED_DESCRIPTOR {
ED_DESCRIPTOR_WORD0 Word0;
TD_DESCRIPTOR *TdTailPointer;
ED_DESCRIPTOR_WORD2 Word2;
struct _ED_DESCRIPTOR *NextED;
} ED_DESCRIPTOR;
#define TD_PTR(p) ((TD_DESCRIPTOR *)((p) << 4))
#define ED_PTR(p) ((ED_DESCRIPTOR *)((p) << 4))
#define RIGHT_SHIFT_4(p) ((UINT32)(p) >> 4)
typedef enum {
CONTROL_LIST,
BULK_LIST,
INTERRUPT_LIST,
ISOCHRONOUS_LIST
} DESCRIPTOR_LIST_TYPE;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,258 @@
/** @file
Provides the definition of Usb Hc Protocol and OHCI controller
private data structure.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _OHCI_PEIM_H
#define _OHCI_PEIM_H
#include <PiPei.h>
#include <Ppi/UsbController.h>
#include <Ppi/UsbHostController.h>
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/TimerLib.h>
#include <Library/IoLib.h>
typedef struct _USB_OHCI_HC_DEV USB_OHCI_HC_DEV;
#include "UsbHcMem.h"
#include "OhciReg.h"
#include "OhciSched.h"
#include "OhciUrb.h"
#include "Descriptor.h"
#define EFI_USB_SPEED_FULL 0x0000
#define EFI_USB_SPEED_LOW 0x0001
#define EFI_USB_SPEED_HIGH 0x0002
#define PAGESIZE 4096
#define HC_1_MICROSECOND 1
#define HC_1_MILLISECOND (1000 * HC_1_MICROSECOND)
#define HC_1_SECOND (1000 * HC_1_MILLISECOND)
#define USB_OHCI_HC_DEV_SIGNATURE SIGNATURE_32('o','h','c','i')
struct _USB_OHCI_HC_DEV {
UINTN Signature;
PEI_USB_HOST_CONTROLLER_PPI UsbHostControllerPpi;
EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
UINT32 UsbHostControllerBaseAddress;
VOID *MemPool;
};
#define PEI_RECOVERY_USB_OHC_DEV_FROM_EHCI_THIS(a) CR (a, USB_OHCI_HC_DEV, UsbHostControllerPpi, USB_OHCI_HC_DEV_SIGNATURE)
//
// Func List
//
/**
Provides software reset for the USB host controller.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.
@param Attributes A bit mask of the reset operation to perform.
@retval EFI_SUCCESS The reset operation succeeded.
@retval EFI_INVALID_PARAMETER Attributes is not valid.
@retval EFI_UNSUPPOURTED The type of reset specified by Attributes is
not currently supported by the host controller.
@retval EFI_DEVICE_ERROR Host controller isn't halted to reset.
**/
EFI_STATUS
InitializeUsbHC (
IN EFI_PEI_SERVICES **PeiServices,
IN USB_OHCI_HC_DEV *Ohc,
IN UINT16 Attributes
);
/**
Submits control transfer to a target USB device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.
@param DeviceAddress The target device address.
@param DeviceSpeed Target device speed.
@param MaximumPacketLength Maximum packet size the default control transfer
endpoint is capable of sending or receiving.
@param Request USB device request to send.
@param TransferDirection Specifies the data direction for the data stage.
@param Data Data buffer to be transmitted or received from USB device.
@param DataLength The size (in bytes) of the data buffer.
@param TimeOut Indicates the maximum timeout, in millisecond.
@param TransferResult Return the result of this control transfer.
@retval EFI_SUCCESS Transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources.
@retval EFI_INVALID_PARAMETER Some parameters are invalid.
@retval EFI_TIMEOUT Transfer failed due to timeout.
@retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error.
**/
EFI_STATUS
EFIAPI
OhciControlTransfer (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_HOST_CONTROLLER_PPI *This,
IN UINT8 DeviceAddress,
IN UINT8 DeviceSpeed,
IN UINT8 MaxPacketLength,
IN EFI_USB_DEVICE_REQUEST *Request,
IN EFI_USB_DATA_DIRECTION TransferDirection,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
);
/**
Submits bulk transfer to a bulk endpoint of a USB device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.
@param DeviceAddress Target device address.
@param EndPointAddress Endpoint number and its direction in bit 7.
@param MaxiPacketLength Maximum packet size the endpoint is capable of
sending or receiving.
@param Data A pointers to the buffers of data to transmit
from or receive into.
@param DataLength The lenght of the data buffer.
@param DataToggle On input, the initial data toggle for the transfer;
On output, it is updated to to next data toggle to use of
the subsequent bulk transfer.
@param TimeOut Indicates the maximum time, in millisecond, which the
transfer is allowed to complete.
@param TransferResult A pointer to the detailed result information of the
bulk transfer.
@retval EFI_SUCCESS The transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
@retval EFI_INVALID_PARAMETER Parameters are invalid.
@retval EFI_TIMEOUT The transfer failed due to timeout.
@retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
**/
EFI_STATUS
EFIAPI
OhciBulkTransfer (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_HOST_CONTROLLER_PPI *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaxPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
);
/**
Retrieves the number of root hub ports.
@param[in] PeiServices The pointer to the PEI Services Table.
@param[in] This The pointer to this instance of the
PEI_USB_HOST_CONTROLLER_PPI.
@param[out] NumOfPorts The pointer to the number of the root hub ports.
@retval EFI_SUCCESS The port number was retrieved successfully.
@retval EFI_INVALID_PARAMETER PortNumber is NULL.
**/
EFI_STATUS
EFIAPI
OhciGetRootHubNumOfPorts (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_HOST_CONTROLLER_PPI *This,
OUT UINT8 *NumOfPorts
);
/**
Retrieves the current status of a USB root hub port.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.
@param PortNumber The root hub port to retrieve the state from.
@param PortStatus Variable to receive the port state.
@retval EFI_SUCCESS The status of the USB root hub port specified.
by PortNumber was returned in PortStatus.
@retval EFI_INVALID_PARAMETER PortNumber is invalid.
**/
EFI_STATUS
EFIAPI
OhciGetRootHubPortStatus (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_HOST_CONTROLLER_PPI *This,
IN UINT8 PortNumber,
OUT EFI_USB_PORT_STATUS *PortStatus
);
/**
Sets a feature for the specified root hub port.
@param This A pointer to the EFI_USB_HC_PROTOCOL.
@param PortNumber Specifies the root hub port whose feature
is requested to be set.
@param PortFeature Indicates the feature selector associated
with the feature set request.
@retval EFI_SUCCESS The feature specified by PortFeature was set for the
USB root hub port specified by PortNumber.
@retval EFI_DEVICE_ERROR Set feature failed because of hardware issue
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
**/
EFI_STATUS
EFIAPI
OhciSetRootHubPortFeature (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_HOST_CONTROLLER_PPI *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
);
/**
Clears a feature for the specified root hub port.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param This The pointer of PEI_USB_HOST_CONTROLLER_PPI.
@param PortNumber Specifies the root hub port whose feature
is requested to be cleared.
@param PortFeature Indicates the feature selector associated with the
feature clear request.
@retval EFI_SUCCESS The feature specified by PortFeature was cleared
for the USB root hub port specified by PortNumber.
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
**/
EFI_STATUS
EFIAPI
OhciClearRootHubPortFeature (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_HOST_CONTROLLER_PPI *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
);
#endif

View File

@@ -0,0 +1,62 @@
## @file
# OHCI USB Host Controller PEIM
#
# Copyright (c) 2013-2015 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = OhciPei
FILE_GUID = 332A0926-429B-4624-9211-A36B23DF0389
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = OhcPeimEntry
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
Descriptor.h
OhcPeim.c
OhcPeim.h
OhciSched.c
OhciSched.h
OhciReg.c
OhciReg.h
OhciUrb.c
OhciUrb.h
UsbHcMem.c
UsbHcMem.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
QuarkSocPkg/QuarkSocPkg.dec
[LibraryClasses]
IoLib
TimerLib
BaseMemoryLib
PeimEntryPoint
PeiServicesLib
[Ppis]
gPeiUsbHostControllerPpiGuid # PPI ALWAYS_PRODUCED
gPeiUsbControllerPpiGuid # PPI ALWAYS_CONSUMED
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbControllerPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,881 @@
/** @file
This file contains the definination for host controller
register operation routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _OHCI_REGS_H
#define _OHCI_REGS_H
#define HC_STATE_RESET 0x0
#define HC_STATE_RESUME 0x1
#define HC_STATE_OPERATIONAL 0x2
#define HC_STATE_SUSPEND 0x3
#define PERIODIC_ENABLE 0x01
#define ISOCHRONOUS_ENABLE 0x02
#define CONTROL_ENABLE 0x04
#define BULK_ENABLE 0x08
#define CONTROL_BULK_RATIO 0x10
#define HC_FUNCTIONAL_STATE 0x20
#define INTERRUPT_ROUTING 0x40
#define HC_RESET 0x01
#define CONTROL_LIST_FILLED 0x02
#define BULK_LIST_FILLED 0x04
#define CHANGE_OWNER_REQUEST 0x08
#define SCHEDULE_OVERRUN_COUNT 0x10
#define SCHEDULE_OVERRUN 0x00001
#define WRITEBACK_DONE_HEAD 0x00002
#define START_OF_FRAME 0x00004
#define RESUME_DETECT 0x00008
#define UNRECOVERABLE_ERROR 0x00010
#define FRAME_NUMBER_OVERFLOW 0x00020
#define ROOTHUB_STATUS_CHANGE 0x00040
#define OWNERSHIP_CHANGE 0x00080
#define MASTER_INTERRUPT 0x00400
#define CONTROL_HEAD 0x001
#define BULK_HEAD 0x002
#define DONE_HEAD 0x004
#define Hc_HCCA 0x001
#define Hc_PERIODIC_CURRENT 0x002
#define Hc_CONTOL_HEAD 0x004
#define Hc_CONTROL_CURRENT_PTR 0x008
#define Hc_BULK_HEAD 0x010
#define Hc_BULK_CURRENT_PTR 0x020
#define Hc_DONE_HEAD 0x040
#define FRAME_INTERVAL 0x008
#define FS_LARGEST_DATA_PACKET 0x010
#define FRMINT_TOGGLE 0x020
#define FRAME_REMAINING 0x040
#define FRAME_REMAIN_TOGGLE 0x080
#define RH_DESC_A 0x00001
#define RH_DESC_B 0x00002
#define RH_NUM_DS_PORTS 0x00004
#define RH_NO_PSWITCH 0x00008
#define RH_PSWITCH_MODE 0x00010
#define RH_DEVICE_TYPE 0x00020
#define RH_OC_PROT_MODE 0x00040
#define RH_NOC_PROT 0x00080
#define RH_POTPGT 0x00100
#define RH_NO_POTPGT 0x00200
#define RH_DEV_REMOVABLE 0x00400
#define RH_PORT_PWR_CTRL_MASK 0x00800
#define RH_LOCAL_PSTAT 0x00001
#define RH_OC_ID 0x00002
#define RH_REMOTE_WK_ENABLE 0x00004
#define RH_LOCAL_PSTAT_CHANGE 0x00008
#define RH_OC_ID_CHANGE 0x00010
#define RH_CLR_RMT_WK_ENABLE 0x00020
#define RH_CLEAR_PORT_ENABLE 0x0001
#define RH_SET_PORT_ENABLE 0x0002
#define RH_SET_PORT_SUSPEND 0x0004
#define RH_CLEAR_SUSPEND_STATUS 0x0008
#define RH_SET_PORT_RESET 0x0010
#define RH_SET_PORT_POWER 0x0020
#define RH_CLEAR_PORT_POWER 0x0040
#define RH_CONNECT_STATUS_CHANGE 0x10000
#define RH_PORT_ENABLE_STAT_CHANGE 0x20000
#define RH_PORT_SUSPEND_STAT_CHANGE 0x40000
#define RH_OC_INDICATOR_CHANGE 0x80000
#define RH_PORT_RESET_STAT_CHANGE 0x100000
#define RH_CURR_CONNECT_STAT 0x0001
#define RH_PORT_ENABLE_STAT 0x0002
#define RH_PORT_SUSPEND_STAT 0x0004
#define RH_PORT_OC_INDICATOR 0x0008
#define RH_PORT_RESET_STAT 0x0010
#define RH_PORT_POWER_STAT 0x0020
#define RH_LSDEVICE_ATTACHED 0x0040
#define RESET_SYSTEM_BUS (1 << 0)
#define RESET_HOST_CONTROLLER (1 << 1)
#define RESET_CLOCK_GENERATION (1 << 2)
#define RESET_SSE_GLOBAL (1 << 5)
#define RESET_PSPL (1 << 6)
#define RESET_PCPL (1 << 7)
#define RESET_SSEP1 (1 << 9)
#define RESET_SSEP2 (1 << 10)
#define RESET_SSEP3 (1 << 11)
#define ONE_SECOND 1000000
#define ONE_MILLI_SEC 1000
#define MAX_BYTES_PER_TD 0x1000
#define MAX_RETRY_TIMES 100
#define PORT_NUMBER_ON_MAINSTONE2 1
//
// Operational Register Offsets
//
//
// Command & Status Registers Offsets
//
#define HC_REVISION 0x00
#define HC_CONTROL 0x04
#define HC_COMMAND_STATUS 0x08
#define HC_INTERRUPT_STATUS 0x0C
#define HC_INTERRUPT_ENABLE 0x10
#define HC_INTERRUPT_DISABLE 0x14
//
// Memory Pointer Offsets
//
#define HC_HCCA 0x18
#define HC_PERIODIC_CURRENT 0x1C
#define HC_CONTROL_HEAD 0x20
#define HC_CONTROL_CURRENT_PTR 0x24
#define HC_BULK_HEAD 0x28
#define HC_BULK_CURRENT_PTR 0x2C
#define HC_DONE_HEAD 0x30
//
// Frame Register Offsets
//
#define HC_FRM_INTERVAL 0x34
#define HC_FRM_REMAINING 0x38
#define HC_FRM_NUMBER 0x3C
#define HC_PERIODIC_START 0x40
#define HC_LS_THREASHOLD 0x44
//
// Root Hub Register Offsets
//
#define HC_RH_DESC_A 0x48
#define HC_RH_DESC_B 0x4C
#define HC_RH_STATUS 0x50
#define HC_RH_PORT_STATUS 0x54
#define USBHOST_OFFSET_UHCHR 0x64 // Usb Host reset register
#define OHC_BAR_INDEX 0
//
// Usb Host controller register offset
//
#define USBHOST_OFFSET_UHCREV 0x0 // Usb Host revision register
#define USBHOST_OFFSET_UHCHCON 0x4 // Usb Host control register
#define USBHOST_OFFSET_UHCCOMS 0x8 // Usb Host Command Status register
#define USBHOST_OFFSET_UHCINTS 0xC // Usb Host Interrupt Status register
#define USBHOST_OFFSET_UHCINTE 0x10 // Usb Host Interrupt Enable register
#define USBHOST_OFFSET_UHCINTD 0x14 // Usb Host Interrupt Disable register
#define USBHOST_OFFSET_UHCHCCA 0x18 // Usb Host Controller Communication Area
#define USBHOST_OFFSET_UHCPCED 0x1C // Usb Host Period Current Endpoint Descriptor
#define USBHOST_OFFSET_UHCCHED 0x20 // Usb Host Control Head Endpoint Descriptor
#define USBHOST_OFFSET_UHCCCED 0x24 // Usb Host Control Current Endpoint Descriptor
#define USBHOST_OFFSET_UHCBHED 0x28 // Usb Host Bulk Head Endpoint Descriptor
#define USBHOST_OFFSET_UHCBCED 0x2C // Usb Host Bulk Current Endpoint Descriptor
#define USBHOST_OFFSET_UHCDHEAD 0x30 // Usb Host Done Head register
#define USBHOST_OFFSET_UHCFMI 0x34 // Usb Host Frame Interval register
#define USBHOST_OFFSET_UHCFMR 0x38 // Usb Host Frame Remaining register
#define USBHOST_OFFSET_UHCFMN 0x3C // Usb Host Frame Number register
#define USBHOST_OFFSET_UHCPERS 0x40 // Usb Host Periodic Start register
#define USBHOST_OFFSET_UHCLST 0x44 // Usb Host Low-Speed Threshold register
#define USBHOST_OFFSET_UHCRHDA 0x48 // Usb Host Root Hub Descriptor A register
#define USBHOST_OFFSET_UHCRHDB 0x4C // Usb Host Root Hub Descriptor B register
#define USBHOST_OFFSET_UHCRHS 0x50 // Usb Host Root Hub Status register
#define USBHOST_OFFSET_UHCRHPS1 0x54 // Usb Host Root Hub Port Status 1 register
//
// Usb Host controller register bit fields
//
#pragma pack(1)
typedef struct {
UINT8 ProgInterface;
UINT8 SubClassCode;
UINT8 BaseCode;
} USB_CLASSC;
typedef struct {
UINT32 Revision:8;
UINT32 Rsvd:24;
} HcREVISION;
typedef struct {
UINT32 ControlBulkRatio:2;
UINT32 PeriodicEnable:1;
UINT32 IsochronousEnable:1;
UINT32 ControlEnable:1;
UINT32 BulkEnable:1;
UINT32 FunctionalState:2;
UINT32 InterruptRouting:1;
UINT32 RemoteWakeup:1;
UINT32 RemoteWakeupEnable:1;
UINT32 Reserved:21;
} HcCONTROL;
typedef struct {
UINT32 HcReset:1;
UINT32 ControlListFilled:1;
UINT32 BulkListFilled:1;
UINT32 ChangeOwnerRequest:1;
UINT32 Reserved1:12;
UINT32 ScheduleOverrunCount:2;
UINT32 Reserved:14;
} HcCOMMAND_STATUS;
typedef struct {
UINT32 SchedulingOverrun:1;
UINT32 WriteBackDone:1;
UINT32 Sof:1;
UINT32 ResumeDetected:1;
UINT32 UnrecoverableError:1;
UINT32 FrameNumOverflow:1;
UINT32 RHStatusChange:1;
UINT32 Reserved1:23;
UINT32 OwnerChange:1;
UINT32 Reserved2:1;
} HcINTERRUPT_STATUS;
typedef struct {
UINT32 SchedulingOverrunInt:1;
UINT32 WriteBackDoneInt:1;
UINT32 SofInt:1;
UINT32 ResumeDetectedInt:1;
UINT32 UnrecoverableErrorInt:1;
UINT32 FrameNumOverflowInt:1;
UINT32 RHStatusChangeInt:1;
UINT32 Reserved:23;
UINT32 OwnerChangedInt:1;
UINT32 MasterInterruptEnable:1;
} HcINTERRUPT_CONTROL;
typedef struct {
UINT32 Rerserved:8;
UINT32 Hcca:24;
} HcHCCA;
typedef struct {
UINT32 Reserved:4;
UINT32 MemoryPtr:28;
} HcMEMORY_PTR;
typedef struct {
UINT32 FrameInterval:14;
UINT32 Reserved:2;
UINT32 FSMaxDataPacket:15;
UINT32 FrmIntervalToggle:1;
} HcFRM_INTERVAL;
typedef struct {
UINT32 FrameRemaining:14;
UINT32 Reserved:17;
UINT32 FrameRemainingToggle:1;
} HcFRAME_REMAINING;
typedef struct {
UINT32 FrameNumber:16;
UINT32 Reserved:16;
} HcFRAME_NUMBER;
typedef struct {
UINT32 PeriodicStart:14;
UINT32 Reserved:18;
} HcPERIODIC_START;
typedef struct {
UINT32 LsThreshold:12;
UINT32 Reserved:20;
} HcLS_THRESHOLD;
typedef struct {
UINT32 NumDownStrmPorts:8;
UINT32 PowerSwitchMode:1;
UINT32 NoPowerSwitch:1;
UINT32 DeviceType:1;
UINT32 OverCurrentProtMode:1;
UINT32 NoOverCurrentProtMode:1;
UINT32 Reserved:11;
UINT32 PowerOnToPowerGoodTime:8;
} HcRH_DESC_A;
typedef struct {
UINT32 DeviceRemovable:16;
UINT32 PortPowerControlMask:16;
} HcRH_DESC_B;
typedef struct {
UINT32 LocalPowerStat:1;
UINT32 OverCurrentIndicator:1;
UINT32 Reserved1:13;
UINT32 DevRemoteWakeupEnable:1;
UINT32 LocalPowerStatChange:1;
UINT32 OverCurrentIndicatorChange:1;
UINT32 Reserved2:13;
UINT32 ClearRemoteWakeupEnable:1;
} HcRH_STATUS;
typedef struct {
UINT32 CurrentConnectStat:1;
UINT32 EnableStat:1;
UINT32 SuspendStat:1;
UINT32 OCIndicator:1;
UINT32 ResetStat:1;
UINT32 Reserved1:3;
UINT32 PowerStat:1;
UINT32 LsDeviceAttached:1;
UINT32 Reserved2:6;
UINT32 ConnectStatChange:1;
UINT32 EnableStatChange:1;
UINT32 SuspendStatChange:1;
UINT32 OCIndicatorChange:1;
UINT32 ResetStatChange:1;
UINT32 Reserved3:11;
} HcRHPORT_STATUS;
typedef struct {
UINT32 FSBIR:1;
UINT32 FHR:1;
UINT32 CGR:1;
UINT32 SSDC:1;
UINT32 UIT:1;
UINT32 SSE:1;
UINT32 PSPL:1;
UINT32 PCPL:1;
UINT32 Reserved0:1;
UINT32 SSEP1:1;
UINT32 SSEP2:1;
UINT32 SSEP3:1;
UINT32 Reserved1:20;
} HcRESET;
#pragma pack()
//
// Func List
//
/**
Get OHCI operational reg value
@param Ohc UHC private data
@param Offset Offset of the operational reg
@retval Value of the register
**/
UINT32
OhciGetOperationalReg (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Offset
);
/**
Set OHCI operational reg value
@param Ohc UHC private data
@param Offset Offset of the operational reg
@param Value Value to set
@retval EFI_SUCCESS Value set to the reg
**/
EFI_STATUS
OhciSetOperationalReg (
USB_OHCI_HC_DEV *Ohc,
IN UINT32 Offset,
IN UINT32 *Value
);
/**
Get HcRevision reg value
@param Ohc UHC private data
@retval Value of the register
**/
UINT32
OhciGetHcRevision (
USB_OHCI_HC_DEV *Ohc
);
/**
Set HcReset reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcReset (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Field,
IN UINT32 Value
);
/**
Get specific field of HcReset reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcReset (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Field
);
/**
Set HcControl reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
);
/**
Get specific field of HcControl reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set HcCommand reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetHcCommandStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
);
/**
Get specific field of HcCommand reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcCommandStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Clear specific fields of Interrupt Status
@param Ohc UHC private data
@param Field Field to clear
@retval EFI_SUCCESS Fields cleared
**/
EFI_STATUS
OhciClearInterruptStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Get fields of HcInterrupt reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcInterruptStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set Interrupt Control reg value
@param Ohc UHC private data
@param StatEnable Enable or Disable
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetInterruptControl (
IN USB_OHCI_HC_DEV *Ohc,
IN BOOLEAN StatEnable,
IN UINTN Field,
IN UINT32 Value
);
/**
Get field of HcInterruptControl reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetHcInterruptControl (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set memory pointer of specific type
@param Ohc UHC private data
@param PointerType Type of the pointer to set
@param Value Value to set
@retval EFI_SUCCESS Memory pointer set
**/
EFI_STATUS
OhciSetMemoryPointer(
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN PointerType,
IN VOID *Value
);
/**
Get memory pointer of specific type
@param Ohc UHC private data
@param PointerType Type of pointer
@retval Memory pointer of the specific type
**/
VOID *
OhciGetMemoryPointer (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN PointerType
);
/**
Set Frame Interval value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameInterval (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
);
/**
Get field of frame interval reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetFrameInterval (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set Frame Remaining reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameRemaining (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
);
/**
Get value of frame remaining reg
@param Ohc UHC private data
@param Field Field to get
@retval Value of frame remaining reg
**/
UINT32
OhciGetFrameRemaining (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set frame number reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetFrameNumber(
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
);
/**
Get frame number reg value
@param Ohc UHC private data
@retval Value of frame number reg
**/
UINT32
OhciGetFrameNumber (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Set period start reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetPeriodicStart (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
);
/**
Get periodic start reg value
@param Ohc UHC private data
@param Value of periodic start reg
**/
UINT32
OhciGetPeriodicStart (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Set Ls Threshold reg value
@param Ohc UHC private data
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetLsThreshold (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Value
);
/**
Get Ls Threshold reg value
@param Ohc UHC private data
@retval Value of Ls Threshold reg
**/
UINT32
OhciGetLsThreshold (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Set Root Hub Descriptor reg value
@param Ohc UHC private data
@param Field Field to set
@param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubDescriptor (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field,
IN UINT32 Value
);
/**
Get Root Hub Descriptor reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetRootHubDescriptor (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set Root Hub Status reg value
@param Ohc UHC private data
@param Field Field to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Get Root Hub Status reg value
@param Ohc UHC private data
@param Field Field to get
@retval Value of the field
**/
UINT32
OhciGetRootHubStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINTN Field
);
/**
Set Root Hub Port Status reg value
@param Ohc UHC private data
@param Index Index of the port
@param Field Field to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetRootHubPortStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Index,
IN UINTN Field
);
/**
Get Root Hub Port Status reg value
@param Ohc UHC private data
@param Index Index of the port
@param Field Field to get
@retval Value of the field and index
**/
UINT32
OhciReadRootHubPortStatus (
IN USB_OHCI_HC_DEV *Ohc,
IN UINT32 Index,
IN UINTN Field
);
#endif

View File

@@ -0,0 +1,229 @@
/** @file
OHCI transfer scheduling routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "OhcPeim.h"
/**
Convert Error code from OHCI format to EFI format
@Param ErrorCode ErrorCode in OHCI format
@retval ErrorCode in EFI format
**/
UINT32
ConvertErrorCode (
IN UINT32 ErrorCode
)
{
UINT32 TransferResult;
switch (ErrorCode) {
case TD_NO_ERROR:
TransferResult = EFI_USB_NOERROR;
break;
case TD_TOBE_PROCESSED:
case TD_TOBE_PROCESSED_2:
TransferResult = EFI_USB_ERR_NOTEXECUTE;
break;
case TD_DEVICE_STALL:
TransferResult = EFI_USB_ERR_STALL;
break;
case TD_BUFFER_OVERRUN:
case TD_BUFFER_UNDERRUN:
TransferResult = EFI_USB_ERR_BUFFER;
break;
case TD_CRC_ERROR:
TransferResult = EFI_USB_ERR_CRC;
break;
case TD_NO_RESPONSE:
TransferResult = EFI_USB_ERR_TIMEOUT;
break;
case TD_BITSTUFFING_ERROR:
TransferResult = EFI_USB_ERR_BITSTUFF;
break;
default:
TransferResult = EFI_USB_ERR_SYSTEM;
}
return TransferResult;
}
/**
Check TDs Results
@Param Ohc UHC private data
@Param Td TD_DESCRIPTOR
@Param Result Result to return
@retval TRUE means OK
@retval FLASE means Error or Short packet
**/
BOOLEAN
OhciCheckTDsResults (
IN USB_OHCI_HC_DEV *Ohc,
IN TD_DESCRIPTOR *Td,
OUT UINT32 *Result
)
{
UINT32 TdCompletionCode;
*Result = EFI_USB_NOERROR;
while (Td) {
TdCompletionCode = Td->Word0.ConditionCode;
*Result |= ConvertErrorCode(TdCompletionCode);
//
// if any error encountered, stop processing the left TDs.
//
if (*Result) {
return FALSE;
}
Td = Td->NextTDPointer;
}
return TRUE;
}
/**
Check the task status on an ED
@Param Ed Pointer to the ED task that TD hooked on
@Param HeadTd TD header for current transaction
@retval Task Status Code
**/
UINT32
CheckEDStatus (
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd
)
{
while(HeadTd != NULL) {
if (HeadTd->Word0.ConditionCode != 0) {
return HeadTd->Word0.ConditionCode;
}
HeadTd = HeadTd->NextTDPointer;
}
if (OhciGetEDField (Ed, ED_TDHEAD_PTR) != OhciGetEDField (Ed, ED_TDTAIL_PTR)) {
return TD_TOBE_PROCESSED;
}
return TD_NO_ERROR;
}
/**
Check the task status
@Param Ohc UHC private data
@Param ListType Pipe type
@Param Ed Pointer to the ED task hooked on
@Param HeadTd Head of TD corresponding to the task
@Param ErrorCode return the ErrorCode
@retval EFI_SUCCESS Task done
@retval EFI_NOT_READY Task on processing
@retval EFI_DEVICE_ERROR Some error occured
**/
EFI_STATUS
CheckIfDone (
IN USB_OHCI_HC_DEV *Ohc,
IN DESCRIPTOR_LIST_TYPE ListType,
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd,
OUT UINT32 *ErrorCode
)
{
*ErrorCode = TD_TOBE_PROCESSED;
switch (ListType) {
case CONTROL_LIST:
if (OhciGetHcCommandStatus (Ohc, CONTROL_LIST_FILLED) != 0) {
return EFI_NOT_READY;
}
break;
case BULK_LIST:
if (OhciGetHcCommandStatus (Ohc, BULK_LIST_FILLED) != 0) {
return EFI_NOT_READY;
}
break;
default:
break;
}
*ErrorCode = CheckEDStatus (Ed, HeadTd);
if (*ErrorCode == TD_NO_ERROR) {
return EFI_SUCCESS;
} else if (*ErrorCode == TD_TOBE_PROCESSED) {
return EFI_NOT_READY;
} else {
return EFI_DEVICE_ERROR;
}
}
/**
Convert TD condition code to Efi Status
@Param ConditionCode Condition code to convert
@retval EFI_SUCCESS No error occured
@retval EFI_NOT_READY TD still on processing
@retval EFI_DEVICE_ERROR Error occured in processing TD
**/
EFI_STATUS
OhciTDConditionCodeToStatus (
IN UINT32 ConditionCode
)
{
if (ConditionCode == TD_NO_ERROR) {
return EFI_SUCCESS;
}
if (ConditionCode == TD_TOBE_PROCESSED) {
return EFI_NOT_READY;
}
return EFI_DEVICE_ERROR;
}

View File

@@ -0,0 +1,114 @@
/** @file
This file contains the definination for host controller schedule routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _OHCI_SCHED_H
#define _OHCI_SCHED_H
#include "Descriptor.h"
#define HCCA_MEM_SIZE 256
#define GRID_SIZE 16
#define GRID_SHIFT 4
/**
Convert Error code from OHCI format to EFI format
@Param ErrorCode ErrorCode in OHCI format
@retval ErrorCode in EFI format
**/
UINT32
ConvertErrorCode (
IN UINT32 ErrorCode
);
/**
Check TDs Results
@Param Ohc UHC private data
@Param Td TD_DESCRIPTOR
@Param Result Result to return
@retval TRUE means OK
@retval FLASE means Error or Short packet
**/
BOOLEAN
OhciCheckTDsResults (
IN USB_OHCI_HC_DEV *Ohc,
IN TD_DESCRIPTOR *Td,
OUT UINT32 *Result
);
/**
Check the task status on an ED
@Param Ed Pointer to the ED task that TD hooked on
@Param HeadTd TD header for current transaction
@retval Task Status Code
**/
UINT32
CheckEDStatus (
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd
);
/**
Check the task status
@Param Ohc UHC private data
@Param ListType Pipe type
@Param Ed Pointer to the ED task hooked on
@Param HeadTd Head of TD corresponding to the task
@Param ErrorCode return the ErrorCode
@retval EFI_SUCCESS Task done
@retval EFI_NOT_READY Task on processing
@retval EFI_DEVICE_ERROR Some error occured
**/
EFI_STATUS
CheckIfDone (
IN USB_OHCI_HC_DEV *Ohc,
IN DESCRIPTOR_LIST_TYPE ListType,
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd,
OUT UINT32 *ErrorCode
);
/**
Convert TD condition code to Efi Status
@Param ConditionCode Condition code to convert
@retval EFI_SUCCESS No error occured
@retval EFI_NOT_READY TD still on processing
@retval EFI_DEVICE_ERROR Error occured in processing TD
**/
EFI_STATUS
OhciTDConditionCodeToStatus (
IN UINT32 ConditionCode
);
#endif

View File

@@ -0,0 +1,566 @@
/** @file
This file contains URB request, each request is warpped in a
URB (Usb Request Block).
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "OhcPeim.h"
/**
Create a TD
@Param Ohc UHC private data
@retval TD structure pointer
**/
TD_DESCRIPTOR *
OhciCreateTD (
IN USB_OHCI_HC_DEV *Ohc
)
{
TD_DESCRIPTOR *Td;
Td = UsbHcAllocateMem(Ohc->MemPool, sizeof(TD_DESCRIPTOR));
if (Td == NULL) {
return NULL;
}
Td->CurrBufferPointer = NULL;
Td->NextTD = NULL;
Td->BufferEndPointer = NULL;
Td->NextTDPointer = NULL;
return Td;
}
/**
Free a TD
@Param Ohc UHC private data
@Param Td Pointer to a TD to free
@retval EFI_SUCCESS TD freed
**/
EFI_STATUS
OhciFreeTD (
IN USB_OHCI_HC_DEV *Ohc,
IN TD_DESCRIPTOR *Td
)
{
if (Td == NULL) {
return EFI_SUCCESS;
}
UsbHcFreeMem(Ohc->MemPool, Td, sizeof(TD_DESCRIPTOR));
return EFI_SUCCESS;
}
/**
Create a ED
@Param Ohc Device private data
@retval ED descriptor pointer
**/
ED_DESCRIPTOR *
OhciCreateED (
USB_OHCI_HC_DEV *Ohc
)
{
ED_DESCRIPTOR *Ed;
Ed = UsbHcAllocateMem(Ohc->MemPool, sizeof (ED_DESCRIPTOR));
if (Ed == NULL) {
return NULL;
}
Ed->Word0.Skip = 1;
Ed->TdTailPointer = NULL;
Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) NULL);
Ed->NextED = NULL;
return Ed;
}
/**
Free a ED
@Param Ohc UHC private data
@Param Ed Pointer to a ED to free
@retval EFI_SUCCESS ED freed
**/
EFI_STATUS
OhciFreeED (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *Ed
)
{
if (Ed == NULL) {
return EFI_SUCCESS;
}
UsbHcFreeMem(Ohc->MemPool, Ed, sizeof(ED_DESCRIPTOR));
return EFI_SUCCESS;
}
/**
Free ED
@Param Ohc Device private data
@Param Ed Pointer to a ED to free
@retval EFI_SUCCESS ED freed
**/
EFI_STATUS
OhciFreeAllTDFromED (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *Ed
)
{
TD_DESCRIPTOR *HeadTd;
TD_DESCRIPTOR *TailTd;
TD_DESCRIPTOR *Td;
TD_DESCRIPTOR *TempTd;
if (Ed == NULL) {
return EFI_SUCCESS;
}
HeadTd = TD_PTR (Ed->Word2.TdHeadPointer);
TailTd = Ed->TdTailPointer;
Td = HeadTd;
while (Td != TailTd) {
TempTd = Td;
Td = Td->NextTDPointer;
OhciFreeTD (Ohc, TempTd);
}
return EFI_SUCCESS;
}
/**
Attach an ED
@Param Ed Ed to be attached
@Param NewEd Ed to attach
@retval EFI_SUCCESS NewEd attached to Ed
@retval EFI_INVALID_PARAMETER Ed is NULL
**/
EFI_STATUS
OhciAttachED (
IN ED_DESCRIPTOR *Ed,
IN ED_DESCRIPTOR *NewEd
)
{
ED_DESCRIPTOR *Temp;
if (Ed == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Ed->NextED == NULL){
Ed->NextED = NewEd;
} else {
Temp = Ed->NextED;
Ed->NextED = NewEd;
NewEd->NextED = Temp;
}
return EFI_SUCCESS;
}
/**
Attach an ED to an ED list
@Param OHC UHC private data
@Param ListType Type of the ED list
@Param Ed ED to attach
@Param EdList ED list to be attached
@retval EFI_SUCCESS ED attached to ED list
**/
EFI_STATUS
OhciAttachEDToList (
IN USB_OHCI_HC_DEV *Ohc,
IN DESCRIPTOR_LIST_TYPE ListType,
IN ED_DESCRIPTOR *Ed,
IN ED_DESCRIPTOR *EdList
)
{
ED_DESCRIPTOR *HeadEd;
switch(ListType) {
case CONTROL_LIST:
HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_CONTROL_HEAD);
if (HeadEd == NULL) {
OhciSetMemoryPointer (Ohc, HC_CONTROL_HEAD, Ed);
} else {
OhciAttachED (HeadEd, Ed);
}
break;
case BULK_LIST:
HeadEd = (ED_DESCRIPTOR *) OhciGetMemoryPointer (Ohc, HC_BULK_HEAD);
if (HeadEd == NULL) {
OhciSetMemoryPointer (Ohc, HC_BULK_HEAD, Ed);
} else {
OhciAttachED (HeadEd, Ed);
}
break;
case INTERRUPT_LIST:
OhciAttachED (EdList, Ed);
break;
default:
ASSERT (FALSE);
}
return EFI_SUCCESS;
}
/**
Link Td2 to the end of Td1
@Param Td1 TD to be linked
@Param Td2 TD to link
@retval EFI_SUCCESS TD successfully linked
@retval EFI_INVALID_PARAMETER Td1 is NULL
**/
EFI_STATUS
OhciLinkTD (
IN TD_DESCRIPTOR *Td1,
IN TD_DESCRIPTOR *Td2
)
{
TD_DESCRIPTOR *TempTd;
if (Td1 == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Td1 == Td2) {
return EFI_SUCCESS;
}
TempTd = Td1;
while (TempTd->NextTD != NULL) {
TempTd = TempTd->NextTD;
}
TempTd->NextTD = Td2;
TempTd->NextTDPointer = Td2;
return EFI_SUCCESS;
}
/**
Attach TD list to ED
@Param Ed ED which TD list attach on
@Param HeadTd Head of the TD list to attach
@retval EFI_SUCCESS TD list attached on the ED
**/
EFI_STATUS
OhciAttachTDListToED (
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd
)
{
TD_DESCRIPTOR *TempTd;
TempTd = TD_PTR (Ed->Word2.TdHeadPointer);
if (TempTd != NULL) {
while (TempTd->NextTD != NULL) {
TempTd = TempTd->NextTD;
}
TempTd->NextTD = HeadTd;
TempTd->NextTDPointer = HeadTd;
} else {
Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 ((UINT32) HeadTd);
}
return EFI_SUCCESS;
}
/**
Set value to ED specific field
@Param Ed ED to be set
@Param Field Field to be set
@Param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetEDField (
IN ED_DESCRIPTOR *Ed,
IN UINT32 Field,
IN UINT32 Value
)
{
if (Field & ED_FUNC_ADD) {
Ed->Word0.FunctionAddress = Value;
}
if (Field & ED_ENDPT_NUM) {
Ed->Word0.EndPointNum = Value;
}
if (Field & ED_DIR) {
Ed->Word0.Direction = Value;
}
if (Field & ED_SPEED) {
Ed->Word0.Speed = Value;
}
if (Field & ED_SKIP) {
Ed->Word0.Skip = Value;
}
if (Field & ED_FORMAT) {
Ed->Word0.Format = Value;
}
if (Field & ED_MAX_PACKET) {
Ed->Word0.MaxPacketSize = Value;
}
if (Field & ED_PDATA) {
Ed->Word0.FreeSpace = Value;
}
if (Field & ED_ZERO) {
Ed->Word2.Zero = Value;
}
if (Field & ED_TDTAIL_PTR) {
Ed->TdTailPointer = (VOID *) Value;
}
if (Field & ED_HALTED) {
Ed->Word2.Halted = Value;
}
if (Field & ED_DTTOGGLE) {
Ed->Word2.ToggleCarry = Value;
}
if (Field & ED_TDHEAD_PTR) {
Ed->Word2.TdHeadPointer = RIGHT_SHIFT_4 (Value);
}
if (Field & ED_NEXT_EDPTR) {
Ed->NextED = (VOID *) Value;
}
return EFI_SUCCESS;
}
/**
Get value from an ED's specific field
@Param Ed ED pointer
@Param Field Field to get value from
@retval Value of the field
**/
UINT32
OhciGetEDField (
IN ED_DESCRIPTOR *Ed,
IN UINT32 Field
)
{
switch (Field) {
case ED_FUNC_ADD:
return Ed->Word0.FunctionAddress;
break;
case ED_ENDPT_NUM:
return Ed->Word0.EndPointNum;
break;
case ED_DIR:
return Ed->Word0.Direction;
break;
case ED_SPEED:
return Ed->Word0.Speed;
break;
case ED_SKIP:
return Ed->Word0.Skip;
break;
case ED_FORMAT:
return Ed->Word0.Format;
break;
case ED_MAX_PACKET:
return Ed->Word0.MaxPacketSize;
break;
case ED_TDTAIL_PTR:
return (UINT32) Ed->TdTailPointer;
break;
case ED_HALTED:
return Ed->Word2.Halted;
break;
case ED_DTTOGGLE:
return Ed->Word2.ToggleCarry;
break;
case ED_TDHEAD_PTR:
return Ed->Word2.TdHeadPointer << 4;
break;
case ED_NEXT_EDPTR:
return (UINT32) Ed->NextED;
break;
default:
ASSERT (FALSE);
}
return 0;
}
/**
Set value to TD specific field
@Param Td TD to be set
@Param Field Field to be set
@Param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetTDField (
IN TD_DESCRIPTOR *Td,
IN UINT32 Field,
IN UINT32 Value
)
{
if (Field & TD_PDATA) {
Td->Word0.Reserved = Value;
}
if (Field & TD_BUFFER_ROUND) {
Td->Word0.BufferRounding = Value;
}
if (Field & TD_DIR_PID) {
Td->Word0.DirPID = Value;
}
if (Field & TD_DELAY_INT) {
Td->Word0.DelayInterrupt = Value;
}
if (Field & TD_DT_TOGGLE) {
Td->Word0.DataToggle = Value | 0x2;
}
if (Field & TD_ERROR_CNT) {
Td->Word0.ErrorCount = Value;
}
if (Field & TD_COND_CODE) {
Td->Word0.ConditionCode = Value;
}
if (Field & TD_CURR_BUFFER_PTR) {
Td->CurrBufferPointer = (VOID *) Value;
}
if (Field & TD_NEXT_PTR) {
Td->NextTD = (VOID *) Value;
}
if (Field & TD_BUFFER_END_PTR) {
Td->BufferEndPointer = (VOID *) Value;
}
return EFI_SUCCESS;
}
/**
Get value from ED specific field
@Param Td TD pointer
@Param Field Field to get value from
@retval Value of the field
**/
UINT32
OhciGetTDField (
IN TD_DESCRIPTOR *Td,
IN UINT32 Field
)
{
switch (Field){
case TD_BUFFER_ROUND:
return Td->Word0.BufferRounding;
break;
case TD_DIR_PID:
return Td->Word0.DirPID;
break;
case TD_DELAY_INT:
return Td->Word0.DelayInterrupt;
break;
case TD_DT_TOGGLE:
return Td->Word0.DataToggle;
break;
case TD_ERROR_CNT:
return Td->Word0.ErrorCount;
break;
case TD_COND_CODE:
return Td->Word0.ConditionCode;
break;
case TD_CURR_BUFFER_PTR:
return (UINT32) Td->CurrBufferPointer;
break;
case TD_NEXT_PTR:
return (UINT32) Td->NextTD;
break;
case TD_BUFFER_END_PTR:
return (UINT32) Td->BufferEndPointer;
break;
default:
ASSERT (FALSE);
}
return 0;
}

View File

@@ -0,0 +1,237 @@
/** @file
Provides some data struct used by OHCI controller driver.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _OHCI_URB_H
#define _OHCI_URB_H
#include "Descriptor.h"
//
// Func List
//
/**
Create a TD
@Param Ohc UHC private data
@retval TD structure pointer
**/
TD_DESCRIPTOR *
OhciCreateTD (
IN USB_OHCI_HC_DEV *Ohc
);
/**
Free a TD
@Param Ohc UHC private data
@Param Td Pointer to a TD to free
@retval EFI_SUCCESS TD freed
**/
EFI_STATUS
OhciFreeTD (
IN USB_OHCI_HC_DEV *Ohc,
IN TD_DESCRIPTOR *Td
);
/**
Create a ED
@Param Ohc Device private data
@retval ED descriptor pointer
**/
ED_DESCRIPTOR *
OhciCreateED (
USB_OHCI_HC_DEV *Ohc
);
/**
Free a ED
@Param Ohc UHC private data
@Param Ed Pointer to a ED to free
@retval EFI_SUCCESS ED freed
**/
EFI_STATUS
OhciFreeED (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *Ed
);
/**
Free ED
@Param Ohc Device private data
@Param Ed Pointer to a ED to free
@retval EFI_SUCCESS ED freed
**/
EFI_STATUS
OhciFreeAllTDFromED (
IN USB_OHCI_HC_DEV *Ohc,
IN ED_DESCRIPTOR *Ed
);
/**
Attach an ED
@Param Ed Ed to be attached
@Param NewEd Ed to attach
@retval EFI_SUCCESS NewEd attached to Ed
@retval EFI_INVALID_PARAMETER Ed is NULL
**/
EFI_STATUS
OhciAttachED (
IN ED_DESCRIPTOR *Ed,
IN ED_DESCRIPTOR *NewEd
);
/**
Attach an ED to an ED list
@Param OHC UHC private data
@Param ListType Type of the ED list
@Param Ed ED to attach
@Param EdList ED list to be attached
@retval EFI_SUCCESS ED attached to ED list
**/
EFI_STATUS
OhciAttachEDToList (
IN USB_OHCI_HC_DEV *Ohc,
IN DESCRIPTOR_LIST_TYPE ListType,
IN ED_DESCRIPTOR *Ed,
IN ED_DESCRIPTOR *EdList
);
EFI_STATUS
OhciLinkTD (
IN TD_DESCRIPTOR *Td1,
IN TD_DESCRIPTOR *Td2
);
/**
Attach TD list to ED
@Param Ed ED which TD list attach on
@Param HeadTd Head of the TD list to attach
@retval EFI_SUCCESS TD list attached on the ED
**/
EFI_STATUS
OhciAttachTDListToED (
IN ED_DESCRIPTOR *Ed,
IN TD_DESCRIPTOR *HeadTd
);
/**
Set value to ED specific field
@Param Ed ED to be set
@Param Field Field to be set
@Param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetEDField (
IN ED_DESCRIPTOR *Ed,
IN UINT32 Field,
IN UINT32 Value
);
/**
Get value from an ED's specific field
@Param Ed ED pointer
@Param Field Field to get value from
@retval Value of the field
**/
UINT32
OhciGetEDField (
IN ED_DESCRIPTOR *Ed,
IN UINT32 Field
);
/**
Set value to TD specific field
@Param Td TD to be set
@Param Field Field to be set
@Param Value Value to set
@retval EFI_SUCCESS Value set
**/
EFI_STATUS
OhciSetTDField (
IN TD_DESCRIPTOR *Td,
IN UINT32 Field,
IN UINT32 Value
);
/**
Get value from ED specific field
@Param Td TD pointer
@Param Field Field to get value from
@retval Value of the field
**/
UINT32
OhciGetTDField (
IN TD_DESCRIPTOR *Td,
IN UINT32 Field
);
#endif

View File

@@ -0,0 +1,497 @@
/** @file
Routine procedures for memory allocate/free.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "OhcPeim.h"
/**
Allocate a block of memory to be used by the buffer pool.
Use Redirect memory services to allocate memmory so that USB DMA transfers do
not cause IMR violations on Quark.
@param Pool The buffer pool to allocate memory for.
@param Pages How many pages to allocate.
@return The allocated memory block or NULL if failed.
**/
USBHC_MEM_BLOCK *
UsbHcAllocMemBlock (
IN USBHC_MEM_POOL *Pool,
IN UINTN Pages
)
{
USBHC_MEM_BLOCK *Block;
VOID *BufHost;
VOID *Mapping;
EFI_PHYSICAL_ADDRESS MappedAddr;
EFI_STATUS Status;
UINTN PageNumber;
EFI_PHYSICAL_ADDRESS TempPtr;
Mapping = NULL;
PageNumber = sizeof(USBHC_MEM_BLOCK)/PAGESIZE +1;
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
PageNumber,
&TempPtr
);
if (EFI_ERROR (Status)) {
return NULL;
}
ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);
//
// each bit in the bit array represents USBHC_MEM_UNIT
// bytes of memory in the memory block.
//
ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);
Block = (USBHC_MEM_BLOCK*)(UINTN)TempPtr;
Block->BufLen = EFI_PAGES_TO_SIZE (Pages);
Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8);
PageNumber = (Block->BitsLen)/PAGESIZE +1;
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
PageNumber,
&TempPtr
);
if (EFI_ERROR (Status)) {
return NULL;
}
ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);
Block->Bits = (UINT8 *)(UINTN)TempPtr;
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
Pages,
&TempPtr
);
ZeroMem ((VOID *)(UINTN)TempPtr, Pages*EFI_PAGE_SIZE);
BufHost = (VOID *)(UINTN)TempPtr;
MappedAddr = (EFI_PHYSICAL_ADDRESS) (UINTN) BufHost;
//
// Check whether the data structure used by the host controller
// should be restricted into the same 4G
//
if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) {
return NULL;
}
Block->BufHost = BufHost;
Block->Buf = (UINT8 *) ((UINTN) MappedAddr);
Block->Mapping = Mapping;
Block->Next = NULL;
return Block;
}
/**
Free the memory block from the memory pool.
@param Pool The memory pool to free the block from.
@param Block The memory block to free.
**/
VOID
UsbHcFreeMemBlock (
IN USBHC_MEM_POOL *Pool,
IN USBHC_MEM_BLOCK *Block
)
{
ASSERT ((Pool != NULL) && (Block != NULL));
}
/**
Alloc some memory from the block.
@param Block The memory block to allocate memory from.
@param Units Number of memory units to allocate.
@return The pointer to the allocated memory. If couldn't allocate the needed memory,
the return value is NULL.
**/
VOID *
UsbHcAllocMemFromBlock (
IN USBHC_MEM_BLOCK *Block,
IN UINTN Units
)
{
UINTN Byte;
UINT8 Bit;
UINTN StartByte;
UINT8 StartBit;
UINTN Available;
UINTN Count;
ASSERT ((Block != 0) && (Units != 0));
StartByte = 0;
StartBit = 0;
Available = 0;
for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
//
// If current bit is zero, the corresponding memory unit is
// available, otherwise we need to restart our searching.
// Available counts the consective number of zero bit.
//
if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
Available++;
if (Available >= Units) {
break;
}
NEXT_BIT (Byte, Bit);
} else {
NEXT_BIT (Byte, Bit);
Available = 0;
StartByte = Byte;
StartBit = Bit;
}
}
if (Available < Units) {
return NULL;
}
//
// Mark the memory as allocated
//
Byte = StartByte;
Bit = StartBit;
for (Count = 0; Count < Units; Count++) {
ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) USB_HC_BIT (Bit));
NEXT_BIT (Byte, Bit);
}
return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
}
/**
Insert the memory block to the pool's list of the blocks.
@param Head The head of the memory pool's block list.
@param Block The memory block to insert.
**/
VOID
UsbHcInsertMemBlockToPool (
IN USBHC_MEM_BLOCK *Head,
IN USBHC_MEM_BLOCK *Block
)
{
ASSERT ((Head != NULL) && (Block != NULL));
Block->Next = Head->Next;
Head->Next = Block;
}
/**
Is the memory block empty?
@param Block The memory block to check.
@retval TRUE The memory block is empty.
@retval FALSE The memory block isn't empty.
**/
BOOLEAN
UsbHcIsMemBlockEmpty (
IN USBHC_MEM_BLOCK *Block
)
{
UINTN Index;
for (Index = 0; Index < Block->BitsLen; Index++) {
if (Block->Bits[Index] != 0) {
return FALSE;
}
}
return TRUE;
}
/**
Unlink the memory block from the pool's list.
@param Head The block list head of the memory's pool.
@param BlockToUnlink The memory block to unlink.
**/
VOID
UsbHcUnlinkMemBlock (
IN USBHC_MEM_BLOCK *Head,
IN USBHC_MEM_BLOCK *BlockToUnlink
)
{
USBHC_MEM_BLOCK *Block;
ASSERT ((Head != NULL) && (BlockToUnlink != NULL));
for (Block = Head; Block != NULL; Block = Block->Next) {
if (Block->Next == BlockToUnlink) {
Block->Next = BlockToUnlink->Next;
BlockToUnlink->Next = NULL;
break;
}
}
}
/**
Initialize the memory management pool for the host controller.
@param PciIo The PciIo that can be used to access the host controller.
@param Check4G Whether the host controller requires allocated memory
from one 4G address space.
@param Which4G The 4G memory area each memory allocated should be from.
@retval EFI_SUCCESS The memory pool is initialized.
@retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.
**/
USBHC_MEM_POOL *
UsbHcInitMemPool (
IN BOOLEAN Check4G,
IN UINT32 Which4G
)
{
USBHC_MEM_POOL *Pool;
UINTN PageNumber;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS TempPtr;
PageNumber = sizeof(USBHC_MEM_POOL)/PAGESIZE +1;
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
PageNumber,
&TempPtr
);
if (EFI_ERROR (Status)) {
return NULL;
}
ZeroMem ((VOID *)(UINTN)TempPtr, PageNumber*EFI_PAGE_SIZE);
Pool = (USBHC_MEM_POOL *) ((UINTN) TempPtr);
Pool->Check4G = Check4G;
Pool->Which4G = Which4G;
Pool->Head = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES);
if (Pool->Head == NULL) {
Pool = NULL;
}
return Pool;
}
/**
Release the memory management pool.
@param Pool The USB memory pool to free.
@retval EFI_SUCCESS The memory pool is freed.
@retval EFI_DEVICE_ERROR Failed to free the memory pool.
**/
EFI_STATUS
UsbHcFreeMemPool (
IN USBHC_MEM_POOL *Pool
)
{
USBHC_MEM_BLOCK *Block;
ASSERT (Pool->Head != NULL);
//
// Unlink all the memory blocks from the pool, then free them.
// UsbHcUnlinkMemBlock can't be used to unlink and free the
// first block.
//
for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
UsbHcFreeMemBlock (Pool, Block);
}
UsbHcFreeMemBlock (Pool, Pool->Head);
return EFI_SUCCESS;
}
/**
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
@param Pool The host controller's memory pool.
@param Size Size of the memory to allocate.
@return The allocated memory or NULL.
**/
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
IN UINTN Size
)
{
USBHC_MEM_BLOCK *Head;
USBHC_MEM_BLOCK *Block;
USBHC_MEM_BLOCK *NewBlock;
VOID *Mem;
UINTN AllocSize;
UINTN Pages;
Mem = NULL;
AllocSize = USBHC_MEM_ROUND (Size);
Head = Pool->Head;
ASSERT (Head != NULL);
//
// First check whether current memory blocks can satisfy the allocation.
//
for (Block = Head; Block != NULL; Block = Block->Next) {
Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
if (Mem != NULL) {
ZeroMem (Mem, Size);
break;
}
}
if (Mem != NULL) {
return Mem;
}
//
// Create a new memory block if there is not enough memory
// in the pool. If the allocation size is larger than the
// default page number, just allocate a large enough memory
// block. Otherwise allocate default pages.
//
if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) {
Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1;
} else {
Pages = USBHC_MEM_DEFAULT_PAGES;
}
NewBlock = UsbHcAllocMemBlock (Pool, Pages);
if (NewBlock == NULL) {
DEBUG ((EFI_D_INFO, "UsbHcAllocateMem: failed to allocate block\n"));
return NULL;
}
//
// Add the new memory block to the pool, then allocate memory from it
//
UsbHcInsertMemBlockToPool (Head, NewBlock);
Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
if (Mem != NULL) {
ZeroMem (Mem, Size);
}
return Mem;
}
/**
Free the allocated memory back to the memory pool.
@param Pool The memory pool of the host controller.
@param Mem The memory to free.
@param Size The size of the memory to free.
**/
VOID
UsbHcFreeMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
)
{
USBHC_MEM_BLOCK *Head;
USBHC_MEM_BLOCK *Block;
UINT8 *ToFree;
UINTN AllocSize;
UINTN Byte;
UINTN Bit;
UINTN Count;
Head = Pool->Head;
AllocSize = USBHC_MEM_ROUND (Size);
ToFree = (UINT8 *) Mem;
for (Block = Head; Block != NULL; Block = Block->Next) {
//
// scan the memory block list for the memory block that
// completely contains the memory to free.
//
if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {
//
// compute the start byte and bit in the bit array
//
Byte = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;
Bit = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;
//
// reset associated bits in bit arry
//
for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {
ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit));
NEXT_BIT (Byte, Bit);
}
break;
}
}
//
// If Block == NULL, it means that the current memory isn't
// in the host controller's pool. This is critical because
// the caller has passed in a wrong memory point
//
ASSERT (Block != NULL);
//
// Release the current memory block if it is empty and not the head
//
if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
UsbHcFreeMemBlock (Pool, Block);
}
return ;
}

View File

@@ -0,0 +1,140 @@
/** @file
This file contains the definination for host controller memory
management routines.
Copyright (c) 2013-2015 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _USB_HC_MEM_H_
#define _USB_HC_MEM_H_
#define USB_HC_BIT(a) ((UINTN)(1 << (a)))
#define USB_HC_BIT_IS_SET(Data, Bit) \
((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit)))
#define USB_HC_HIGH_32BIT(Addr64) \
((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF))
typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK;
struct _USBHC_MEM_BLOCK {
UINT8 *Bits; // Bit array to record which unit is allocated
UINTN BitsLen;
UINT8 *Buf;
UINT8 *BufHost;
UINTN BufLen; // Memory size in bytes
VOID *Mapping;
USBHC_MEM_BLOCK *Next;
};
//
// USBHC_MEM_POOL is used to manage the memory used by USB
// host controller. EHCI requires the control memory and transfer
// data to be on the same 4G memory.
//
typedef struct _USBHC_MEM_POOL {
BOOLEAN Check4G;
UINT32 Which4G;
USBHC_MEM_BLOCK *Head;
} USBHC_MEM_POOL;
//
// Memory allocation unit, must be 2^n, n>4
//
#define USBHC_MEM_UNIT 64
#define USBHC_MEM_UNIT_MASK (USBHC_MEM_UNIT - 1)
#define USBHC_MEM_DEFAULT_PAGES 16
#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
//
// Advance the byte and bit to the next bit, adjust byte accordingly.
//
#define NEXT_BIT(Byte, Bit) \
do { \
(Bit)++; \
if ((Bit) > 7) { \
(Byte)++; \
(Bit) = 0; \
} \
} while (0)
/**
Initialize the memory management pool for the host controller.
@param PciIo The PciIo that can be used to access the host controller.
@param Check4G Whether the host controller requires allocated memory
from one 4G address space.
@param Which4G The 4G memory area each memory allocated should be from.
@retval EFI_SUCCESS The memory pool is initialized.
@retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.
**/
USBHC_MEM_POOL *
UsbHcInitMemPool (
IN BOOLEAN Check4G,
IN UINT32 Which4G
);
/**
Release the memory management pool.
@param Pool The USB memory pool to free.
@retval EFI_SUCCESS The memory pool is freed.
@retval EFI_DEVICE_ERROR Failed to free the memory pool.
**/
EFI_STATUS
UsbHcFreeMemPool (
IN USBHC_MEM_POOL *Pool
);
/**
Allocate some memory from the host controller's memory pool
which can be used to communicate with host controller.
@param Pool The host controller's memory pool.
@param Size Size of the memory to allocate.
@return The allocated memory or NULL.
**/
VOID *
UsbHcAllocateMem (
IN USBHC_MEM_POOL *Pool,
IN UINTN Size
);
/**
Free the allocated memory back to the memory pool.
@param Pool The memory pool of the host controller.
@param Mem The memory to free.
@param Size The size of the memory to free.
**/
VOID
UsbHcFreeMem (
IN USBHC_MEM_POOL *Pool,
IN VOID *Mem,
IN UINTN Size
);
#endif