diff options
| author | Manali Kumar <mkkumar@us.ibm.com> | 2015-09-24 18:52:00 -0500 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-12-08 10:24:35 -0600 |
| commit | 1fbe5e7bf5042ee9e7353a169d13eec54c270f04 (patch) | |
| tree | 3cb9fc58e569fa0d22f7f16a6d8b32900e9de2da /src/usr/console | |
| parent | dee70f6f25fb4ed099942b1b3b0a340bd643ff06 (diff) | |
| download | talos-hostboot-1fbe5e7bf5042ee9e7353a169d13eec54c270f04.tar.gz talos-hostboot-1fbe5e7bf5042ee9e7353a169d13eec54c270f04.zip | |
superio driver to control accesss to SIO registers
The SuperIO driver makes accesses to the SIO chip from the console and
pnor module thread safe.
Change-Id: Ib07dea2867d14684806c56cd965b26c95810f7f3
RTC:115576
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/20928
Tested-by: Jenkins Server
Tested-by: Jenkins OP Build CI
Tested-by: Jenkins OP HW
Tested-by: FSP CI Jenkins
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: PRACHI GUPTA <pragupta@us.ibm.com>
Reviewed-by: Richard J. Knight <rjknight@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/console')
| -rw-r--r-- | src/usr/console/HBconfig | 8 | ||||
| -rw-r--r-- | src/usr/console/ast2400.C | 379 |
2 files changed, 142 insertions, 245 deletions
diff --git a/src/usr/console/HBconfig b/src/usr/console/HBconfig index e6b1ebda7..664febd86 100644 --- a/src/usr/console/HBconfig +++ b/src/usr/console/HBconfig @@ -1,4 +1,10 @@ config CONSOLE - default y if BMC_AST2400 + default y if (BMC_AST2400 || CONSOLE_DEFAULT_UART) help Enable console support. + +config CONSOLE_DEFAULT_UART + default n + depends on !BMC_AST2400 + help + Enable a default UART driver for the console. diff --git a/src/usr/console/ast2400.C b/src/usr/console/ast2400.C index 243c9bec1..c56bf02c4 100644 --- a/src/usr/console/ast2400.C +++ b/src/usr/console/ast2400.C @@ -22,6 +22,7 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ +#include <sio/sio.H> #include "uart.H" #include <devicefw/userif.H> #include <lpc/lpcif.H> @@ -32,19 +33,21 @@ namespace CONSOLE { - const uint32_t VUART1_BASE = 0x1E787000; - const uint32_t VUART1_GCTRLA = VUART1_BASE + 0x20; - const uint32_t VUART1_GCTRLB = VUART1_BASE + 0x24; - const uint32_t VUART1_ADDRL = VUART1_BASE + 0x28; - const uint32_t VUART1_ADDRH = VUART1_BASE + 0x2c; - - const uint8_t SERIAL_IRQ = 4; - - const uint8_t SIO_ADDR_REG_2E = 0x2E; - const uint8_t SIO_DATA_REG_2F = 0x2F; - - // used to test config flags related to console outup selection - const uint8_t CONFIG_MASK = 0xC0; + const uint32_t VUART1_BASE = 0x1E787000; + const uint32_t VUART1_GCTRLA = VUART1_BASE + 0x20; + const uint32_t VUART1_GCTRLB = VUART1_BASE + 0x24; + const uint32_t VUART1_ADDRL = VUART1_BASE + 0x28; + const uint32_t VUART1_ADDRH = VUART1_BASE + 0x2c; + + const uint8_t SERIAL_IRQ = 4; + + // Host SerlIRQ interrupt type for SUART1 + const uint8_t RESERVED = 0x00; + const uint8_t LOW_LEVEL_TRIG = 0x01; + const uint8_t RISING_EDGE_TRIG = 0x02; + const uint8_t HIGH_LEVEL_TRIG = 0x03; + // used to test config flags related to console output selection + const uint8_t CONFIG_MASK = 0xC0; /** Overload the base class with Ast2400 specifics. * @@ -53,7 +56,6 @@ namespace CONSOLE */ class Ast2400Uart : public Uart { - public: enum consoleConfig_t { @@ -64,205 +66,65 @@ namespace CONSOLE }; private: - // $TODO RTC:115576 remove these sio write functions when SIO dd code - // is completed - // Perform raw LPC writes to SIO region. - errlHndl_t _writeReg(uint8_t i_addr, uint8_t i_byte) - { - size_t len = sizeof(i_byte); - return deviceWrite(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, - &i_byte, - len, - DEVICE_LPC_ADDRESS(LPC::TRANS_IO, i_addr)); - } - - // write i_data to register i_reg - errlHndl_t writeSIOReg( uint8_t i_reg, uint8_t i_data ) - { - errlHndl_t l_err = NULL; - - do{ - - l_err = _writeReg( SIO_ADDR_REG_2E, i_reg ); - - if(l_err) { break; } - - l_err = _writeReg( SIO_DATA_REG_2F, i_data ); - - }while(0); - - return l_err; - } - - // Perform reads from the SIO register region. - errlHndl_t readSIOReg(uint8_t i_reg, uint8_t &o_byte) - { - errlHndl_t l_err = NULL; - - size_t len = sizeof(o_byte); - - do{ - l_err = deviceWrite( - TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, - &i_reg, - len, - DEVICE_LPC_ADDRESS(LPC::TRANS_IO, SIO_ADDR_REG_2E)); - - if(l_err) { break; } - - l_err = deviceRead( - TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, - &o_byte, - len, - DEVICE_LPC_ADDRESS(LPC::TRANS_IO, SIO_DATA_REG_2F)); - }while(0); - - return l_err; - } - - // setup the AHB access - errlHndl_t ahbSioAddressPrep(uint32_t reg) - { - errlHndl_t l_err = NULL; - - do{ - // Select logical device D (LPC2AHB) - l_err = writeSIOReg( 0x07, 0x0D ); - if( l_err ) { break; } - - /* Enable iLPC->AHB */ - l_err = writeSIOReg( 0x30, 0x01 ); - if( l_err ) { break; } - - /* Address */ - l_err = writeSIOReg(0xF0, (reg >> 24) & 0xff); - if( l_err ) {break; } - - l_err = writeSIOReg(0xF1, (reg >> 16) & 0xff); - if( l_err ) {break; } - - l_err = writeSIOReg(0xF2, (reg >> 8) & 0xff); - if( l_err ) {break; } - - l_err = writeSIOReg(0xF3, (reg ) & 0xff); - if( l_err ) {break; } - - /* bytes per cycle type */ - l_err = writeSIOReg(0xF8, 0x02); - if( l_err ) {break; } - - }while(0); - - return l_err; - } - - errlHndl_t ahbSioWrite(uint32_t reg, uint32_t val ) - { - errlHndl_t l_err = NULL; - - do{ - - l_err = ahbSioAddressPrep( reg); - if( l_err ) { break; } - - /* Write data */ - l_err = writeSIOReg(0xF4, val >> 24); - if( l_err ) { break; } - l_err = writeSIOReg(0xF5, val >> 16); - if( l_err ) { break; } - l_err = writeSIOReg(0xF6, val >> 8); - if( l_err ) { break; } - l_err = writeSIOReg(0xF7, val); - if( l_err ) { break; } - - /* Trigger the write with the magic number */ - l_err = writeSIOReg(0xFe, 0xcf); - - }while(0); - - return l_err; - } - - errlHndl_t ahbSioRead( uint32_t reg, uint32_t &o_data ) - { - errlHndl_t l_err = NULL; - uint8_t tmp_data = 0; - o_data = 0; - - do{ - - l_err = ahbSioAddressPrep(reg); - if(l_err){break;} - - /* Trigger the read - ignore the output data */ - l_err = readSIOReg(0xFE, tmp_data); - if(l_err){break;} - - tmp_data = 0; - - /* Read results */ - l_err = readSIOReg(0xF4, tmp_data ); - if(l_err){;break;} - o_data = tmp_data; - - l_err = readSIOReg(0xF5, tmp_data ); - if(l_err){break;} - o_data = (o_data << 8) | tmp_data; - - l_err = readSIOReg(0xF6, tmp_data ); - if(l_err){break;} - o_data = (o_data << 8) | tmp_data; - - l_err = readSIOReg(0xF7, tmp_data ); - if(l_err){break;} - o_data = (o_data << 8) | tmp_data; - - }while(0); - - return l_err; - } - - private: - void initializeSUART() { errlHndl_t l_errl = NULL; - + uint8_t l_data; + size_t l_len = sizeof(uint8_t); do { - // Select logical device 2 (SUART1) in SI) - l_errl = writeSIOReg( 0x07, 0x02); - if (l_errl) { break; } - // Disable SUART1 to change settings - l_errl = writeSIOReg( 0x30, 0x00 ); + l_data = SIO::DISABLE_DEVICE; + l_errl = deviceOp( DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(l_data), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x30)); if (l_errl) { break; } // Set SUART1 addr to g_uartBase - l_errl = writeSIOReg( 0x60, (g_uartBase >> 8) & 0xFF ); + l_data =(g_uartBase >> 8) & 0xFF; + l_errl = deviceOp( DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(l_data), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x60)); if (l_errl) { break; } - l_errl = writeSIOReg( 0x61, (g_uartBase & 0xFF) ); + l_data = g_uartBase & 0xFF; + l_errl = deviceOp( DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(l_data), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x61)); if (l_errl) { break; } // Set the SerIRQ - l_errl = writeSIOReg( 0x70, SERIAL_IRQ ); + l_data = SERIAL_IRQ; + l_errl = deviceOp( DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(l_data), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x70)); if (l_errl) { break; } - l_errl = writeSIOReg( 0x71, 0x01 ); + l_data = LOW_LEVEL_TRIG; + l_errl = deviceOp( DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(l_data), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x71)); if (l_errl) { break; } - // Enable SUART1 - l_errl = writeSIOReg( 0x30, 0x01 ); // select SIO base enable + l_data = SIO::ENABLE_DEVICE; + l_errl = deviceOp( DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(l_data), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x30)); if (l_errl) { break; } - //@fixme-RTC:115576 - Leaving SIO unlocked for now to allow - // PNOR write/erase to work - // Lock the SIO registers - //l_errl = _writeReg( 0x2e, 0xAA ); - //if (l_errl) { break; } - } while(0); if (l_errl) @@ -279,29 +141,66 @@ namespace CONSOLE { errlHndl_t l_err = NULL; - do{ + do + { uint32_t v; - + size_t l_len = sizeof(v); + /* Enable device 0x0D*/ + uint8_t l_data = SIO::ENABLE_DEVICE; + l_err = deviceOp( DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + (&l_data), + l_len, + DEVICE_SIO_ADDRESS(SIO::iLPC2AHB,0x30)); + if(l_err) { break; } /* configure IRQ level as low */ - l_err = ahbSioRead(VUART1_GCTRLA, v); + l_err = deviceOp( DeviceFW::READ, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(v), + l_len, + DEVICE_AHB_SIO_ADDRESS(VUART1_GCTRLA)); if(l_err){break;} v = v & ~2u; - l_err = ahbSioWrite(VUART1_GCTRLA, v); + l_err = deviceOp(DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(v), + l_len, + DEVICE_AHB_SIO_ADDRESS(VUART1_GCTRLA)); + if(l_err){break;} /* configure the IRQ number */ - l_err = ahbSioRead(VUART1_GCTRLB, v); + l_err = deviceOp( DeviceFW::READ, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(v), + l_len, + DEVICE_AHB_SIO_ADDRESS(VUART1_GCTRLB)); if(l_err){break;} v = (v & ~0xf0u) | ((SERIAL_IRQ << 4)); - l_err = ahbSioWrite(VUART1_GCTRLB,v); + l_err = deviceOp(DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(v), + l_len, + DEVICE_AHB_SIO_ADDRESS(VUART1_GCTRLB)); if(l_err){break;} /* configure the address */ - l_err = ahbSioWrite(VUART1_ADDRL, g_uartBase & 0xff); + v = g_uartBase & 0xff; + l_err = deviceOp(DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(v), + l_len, + DEVICE_AHB_SIO_ADDRESS(VUART1_ADDRL)); if(l_err){break;} - l_err = ahbSioWrite(VUART1_ADDRH, g_uartBase >> 8); + v = g_uartBase >> 8; + l_err = deviceOp(DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(v), + l_len, + DEVICE_AHB_SIO_ADDRESS(VUART1_ADDRH)); + if(l_err){break;} }while(0); @@ -323,21 +222,29 @@ namespace CONSOLE { errlHndl_t l_err = NULL; - do{ + do + { // read the control reg, mask off the enabled bit // and write it back uint32_t reg_value = 0; + size_t l_len = sizeof(reg_value); + l_err = deviceOp(DeviceFW::READ, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(reg_value), + l_len, + DEVICE_AHB_SIO_ADDRESS(VUART1_GCTRLA)); - l_err = ahbSioRead(VUART1_GCTRLA, reg_value ); if(l_err){break;} // mask off the low order bit to mark the vuart as disabled reg_value &= 0xFE; - l_err = ahbSioWrite(VUART1_GCTRLA, reg_value ); + l_err = deviceOp(DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(reg_value), + l_len, + DEVICE_AHB_SIO_ADDRESS(VUART1_GCTRLA)); if(l_err){break;} - - }while(0); if (l_err) @@ -350,14 +257,16 @@ namespace CONSOLE { errlHndl_t l_err = NULL; - do{ - - // select device 2 - UART1 - l_err = writeSIOReg(0x07, 0x02); - if(l_err){break;} - + do + { // clear the uart enable from base ctl reg - l_err = writeSIOReg(0x30, 0); + uint8_t l_data = SIO::DISABLE_DEVICE; + size_t l_len = sizeof(uint8_t); + l_err = deviceOp( DeviceFW::WRITE, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(l_data), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x30)); }while(0); @@ -367,54 +276,36 @@ namespace CONSOLE } }; - virtual void unlockSIO() - { - errlHndl_t l_err = NULL; - do{ - // Unlock the SIO registers - // (write 0xA5 password to offset 0x2E two times) - l_err = _writeReg( SIO_ADDR_REG_2E, 0xA5 ); - if (l_err) { break; } - - l_err = _writeReg( SIO_ADDR_REG_2E, 0xA5 ); - - }while(0); - - if (l_err) - { - errlCommit(l_err, CONSOLE_COMP_ID); - } - - } - - public: + public: virtual void initialize() { // read the SIO register set by the BMC to determine uart config const uint8_t expected_version = INITSERVICE::BOOTCONFIG::BOOT_FLAGS_VERSION_1; - uint8_t this_version = 0x00; errlHndl_t l_err = NULL; - + size_t l_len = sizeof(uint8_t); uint8_t uart_config = 0x00; - do{ - // allow access to the registers - unlockSIO(); - + do + { // verify the boot flags version from register 0x28 - l_err = readSIOReg( 0x28, this_version ); - + l_err = deviceOp( DeviceFW::READ, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(this_version), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x28)); if (l_err) { break; } - // is it the version we expected? if( expected_version == this_version ) { - l_err = readSIOReg(0x2d, uart_config); - + l_err = deviceOp( DeviceFW::READ, + TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL, + &(uart_config), + l_len, + DEVICE_SIO_ADDRESS(SIO::SUART1, 0x2d)); if (l_err) { break; } // determine which config has been selected |

