summaryrefslogtreecommitdiffstats
path: root/src/usr/console
diff options
context:
space:
mode:
authorManali Kumar <mkkumar@us.ibm.com>2015-09-24 18:52:00 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-12-08 10:24:35 -0600
commit1fbe5e7bf5042ee9e7353a169d13eec54c270f04 (patch)
tree3cb9fc58e569fa0d22f7f16a6d8b32900e9de2da /src/usr/console
parentdee70f6f25fb4ed099942b1b3b0a340bd643ff06 (diff)
downloadtalos-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/HBconfig8
-rw-r--r--src/usr/console/ast2400.C379
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
OpenPOWER on IntegriCloud