diff options
Diffstat (limited to 'src/devices/machine/x76f041.cpp')
-rw-r--r-- | src/devices/machine/x76f041.cpp | 149 |
1 files changed, 91 insertions, 58 deletions
diff --git a/src/devices/machine/x76f041.cpp b/src/devices/machine/x76f041.cpp index 366c4f03569..aa96ad90180 100644 --- a/src/devices/machine/x76f041.cpp +++ b/src/devices/machine/x76f041.cpp @@ -14,9 +14,11 @@ */ #include "emu.h" -#include "machine/x76f041.h" +#include "x76f041.h" #include <cstdarg> +#include <tuple> + #define VERBOSE_LEVEL ( 0 ) @@ -25,7 +27,7 @@ inline void ATTR_PRINTF( 3, 4 ) x76f041_device::verboselog( int n_level, const c if( VERBOSE_LEVEL >= n_level ) { va_list v; - char buf[ 32768 ]; + char buf[32768]; va_start( v, s_fmt ); vsprintf( buf, s_fmt, v ); va_end( v ); @@ -33,11 +35,12 @@ inline void ATTR_PRINTF( 3, 4 ) x76f041_device::verboselog( int n_level, const c } } + // device type definition DEFINE_DEVICE_TYPE(X76F041, x76f041_device, "x76f041", "X76F041 Secure SerialFlash") -x76f041_device::x76f041_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock ) - : device_t( mconfig, X76F041, tag, owner, clock ), +x76f041_device::x76f041_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock ) : + device_t( mconfig, X76F041, tag, owner, clock ), device_nvram_interface(mconfig, *this), m_region(*this, DEVICE_SELF), m_cs( 0 ), @@ -169,8 +172,8 @@ uint8_t *x76f041_device::password() void x76f041_device::password_ok() { - if( m_configuration_registers[ CONFIG_CR ] & CR_RETRY_COUNTER_RESET_BIT ) - m_configuration_registers[ CONFIG_RC ] = 0; + if( m_configuration_registers[CONFIG_CR] & CR_RETRY_COUNTER_RESET_BIT ) + m_configuration_registers[CONFIG_RC] = 0; switch( m_command & 0xe0 ) { @@ -233,9 +236,9 @@ void x76f041_device::load_address() verboselog( 1, "-> address: %02x\n", m_address ); - if( ( m_configuration_registers[ CONFIG_CR ] & CR_RETRY_COUNTER_ENABLE_BIT ) != 0 && - m_configuration_registers[ CONFIG_RR ] == m_configuration_registers[ CONFIG_RC ] && - ( m_configuration_registers[ CONFIG_CR ] & CR_UNAUTHORIZED_ACCESS_BITS ) == 0x80 ) + if( ( m_configuration_registers[CONFIG_CR] & CR_RETRY_COUNTER_ENABLE_BIT ) != 0 && + m_configuration_registers[CONFIG_RR] == m_configuration_registers[CONFIG_RC] && + ( m_configuration_registers[CONFIG_CR] & CR_UNAUTHORIZED_ACCESS_BITS ) == 0x80 ) { // No commands are allowed verboselog( 1, "unauthorized access rejected\n" ); @@ -266,9 +269,9 @@ void x76f041_device::load_address() return; } - if( ( m_configuration_registers[ CONFIG_CR ] & CR_RETRY_COUNTER_ENABLE_BIT ) != 0 && - m_configuration_registers[ CONFIG_RR ] == m_configuration_registers[ CONFIG_RC ] && - ( m_configuration_registers[ CONFIG_CR ] & CR_UNAUTHORIZED_ACCESS_BITS ) != 0x80 ) + if( ( m_configuration_registers[CONFIG_CR] & CR_RETRY_COUNTER_ENABLE_BIT ) != 0 && + m_configuration_registers[CONFIG_RR] == m_configuration_registers[CONFIG_RC] && + ( m_configuration_registers[CONFIG_CR] & CR_UNAUTHORIZED_ACCESS_BITS ) != 0x80 ) { // Only configuration commands are allowed verboselog( 1, "unauthorized access rejected\n" ); @@ -278,7 +281,7 @@ void x76f041_device::load_address() return; } - int bcr = m_configuration_registers[ ( m_command & 1 ) ? CONFIG_BCR2 : CONFIG_BCR1 ]; + int bcr = m_configuration_registers[( m_command & 1 ) ? CONFIG_BCR2 : CONFIG_BCR1]; if( ( m_address & 0x80 ) != 0 ) { bcr >>= 4; @@ -287,7 +290,7 @@ void x76f041_device::load_address() if( ( ( m_command & 0xe0 ) == COMMAND_READ && ( bcr & BCR_Z ) != 0 && ( bcr & BCR_T ) != 0 ) || ( ( m_command & 0xe0 ) == COMMAND_WRITE && ( bcr & BCR_Z ) != 0 ) ) { - /* todo: find out when this is really checked. */ + /* TODO: find out when this is really checked. */ verboselog( 1, "command not allowed\n" ); m_state = STATE_STOP; m_sdar = 1; @@ -333,7 +336,7 @@ void x76f041_device::write_scl(int state) case STATE_RESPONSE_TO_RESET: if( m_scl != 0 && state == 0 ) { - m_sdar = ( m_response_to_reset[ m_byte ] >> m_bit ) & 1; + m_sdar = ( m_response_to_reset[m_byte] >> m_bit ) & 1; verboselog( 2, "in response to reset %d (%d/%d)\n", m_sdar, m_byte, m_bit ); m_bit++; @@ -390,7 +393,7 @@ void x76f041_device::write_scl(int state) case STATE_LOAD_COMMAND: m_command = m_shift; verboselog( 1, "-> command: %02x\n", m_command ); - /* todo: verify command is valid? */ + /* TODO: verify command is valid? */ m_state = STATE_LOAD_ADDRESS; break; @@ -400,7 +403,7 @@ void x76f041_device::write_scl(int state) case STATE_LOAD_PASSWORD: verboselog( 1, "-> password: %02x\n", m_shift ); - m_write_buffer[ m_byte++ ] = m_shift; + m_write_buffer[m_byte++] = m_shift; if( m_byte == sizeof( m_write_buffer ) ) { @@ -412,8 +415,8 @@ void x76f041_device::write_scl(int state) m_is_password_accepted = memcmp( password(), m_write_buffer, sizeof( m_write_buffer ) ) == 0; if( !m_is_password_accepted ) { - if( m_configuration_registers[ CONFIG_CR ] & CR_RETRY_COUNTER_ENABLE_BIT ) - m_configuration_registers[ CONFIG_RC ]++; + if( m_configuration_registers[CONFIG_CR] & CR_RETRY_COUNTER_ENABLE_BIT ) + m_configuration_registers[CONFIG_RC]++; } } break; @@ -421,10 +424,10 @@ void x76f041_device::write_scl(int state) case STATE_VERIFY_PASSWORD: verboselog( 1, "-> verify password: %02x\n", m_shift ); - /* todo: this should probably be handled as a command */ + /* TODO: this should probably be handled as a command */ if( m_shift == 0xc0 ) { - /* todo: this should take 10ms before it returns ok. */ + /* TODO: this should take 10ms before it returns ok. */ if( m_is_password_accepted ) { password_ok(); @@ -438,11 +441,11 @@ void x76f041_device::write_scl(int state) case STATE_WRITE_DATA: verboselog( 2, "-> data: %02x\n", m_shift ); - m_write_buffer[ m_byte++ ] = m_shift; + m_write_buffer[m_byte++] = m_shift; if( m_byte == sizeof( m_write_buffer ) ) { - int bcr = m_configuration_registers[ ( m_command & 1 ) ? CONFIG_BCR2 : CONFIG_BCR1 ]; + int bcr = m_configuration_registers[( m_command & 1 ) ? CONFIG_BCR2 : CONFIG_BCR1]; if( ( m_address & 0x80 ) != 0 ) { bcr >>= 4; @@ -456,7 +459,7 @@ void x76f041_device::write_scl(int state) for( m_byte = 0; m_byte < sizeof( m_write_buffer ); m_byte++ ) { int offset = data_offset(); - if( m_write_buffer[ m_byte ] < m_data[ offset ] ) + if( m_write_buffer[m_byte] < m_data[offset] ) { verboselog( 1, "tried to unset bits while in program only mode\n" ); is_unauthorized_write = true; @@ -475,8 +478,8 @@ void x76f041_device::write_scl(int state) for( m_byte = 0; m_byte < sizeof( m_write_buffer ); m_byte++ ) { int offset = data_offset(); - verboselog( 1, "-> data[ %03x ]: %02x\n", offset, m_write_buffer[ m_byte ] ); - m_data[ offset ] = m_write_buffer[ m_byte ]; + verboselog( 1, "-> data[%03x]: %02x\n", offset, m_write_buffer[m_byte] ); + m_data[offset] = m_write_buffer[m_byte]; } m_byte = 0; @@ -489,14 +492,14 @@ void x76f041_device::write_scl(int state) // Unlike normal writes, configuration writes aren't required to be exactly 8 bytes // TODO: Store data in a temporary buffer until the proper end of the command before writing verboselog( 2, "-> data: %02x\n", m_shift ); - m_data[ data_offset() ] = m_shift; + m_data[data_offset()] = m_shift; m_byte++; break; case STATE_WRITE_CONFIGURATION_REGISTERS: - verboselog( 1, "-> configuration register[ %d ]: %02x\n", m_byte, m_shift ); - /* todo: write after all bytes received? */ - m_configuration_registers[ m_byte++ ] = m_shift; + verboselog( 1, "-> configuration register[%d]: %02x\n", m_byte, m_shift ); + /* TODO: write after all bytes received? */ + m_configuration_registers[m_byte++] = m_shift; if( m_byte == sizeof( m_configuration_registers ) ) { @@ -505,13 +508,13 @@ void x76f041_device::write_scl(int state) break; case STATE_PROGRAM_WRITE_PASSWORD: - verboselog( 1, "-> program write password[ %d ]: %02x\n", m_byte, m_shift ); - m_password_temp[ m_byte++ ] = m_shift; + verboselog( 1, "-> program write password[%d]: %02x\n", m_byte, m_shift ); + m_password_temp[m_byte++] = m_shift; if( m_byte == sizeof( m_password_temp ) ) { // Read in the password twice and if the two copies match then write it to the password field - if( memcmp( &m_password_temp[ 0 ], &m_password_temp[ 8 ], sizeof( m_write_password ) ) == 0 ) + if( memcmp( &m_password_temp[0], &m_password_temp[8], sizeof( m_write_password ) ) == 0 ) { std::copy_n( std::begin( m_password_temp ), sizeof( m_write_password ), std::begin ( m_write_password ) ); } @@ -526,12 +529,12 @@ void x76f041_device::write_scl(int state) break; case STATE_PROGRAM_READ_PASSWORD: - verboselog( 1, "-> program read password[ %d ]: %02x\n", m_byte, m_shift ); - m_password_temp[ m_byte++ ] = m_shift; + verboselog( 1, "-> program read password[%d]: %02x\n", m_byte, m_shift ); + m_password_temp[m_byte++] = m_shift; if( m_byte == sizeof( m_password_temp ) ) { - if( memcmp( &m_password_temp[ 0 ], &m_password_temp[ 8 ], sizeof( m_read_password ) ) == 0 ) + if( memcmp( &m_password_temp[0], &m_password_temp[8], sizeof( m_read_password ) ) == 0 ) { std::copy_n( std::begin( m_password_temp ), sizeof( m_read_password ), std::begin ( m_read_password ) ); } @@ -546,12 +549,12 @@ void x76f041_device::write_scl(int state) break; case STATE_PROGRAM_CONFIGURATION_PASSWORD: - verboselog( 1, "-> program configuration password[ %d ]: %02x\n", m_byte, m_shift ); - m_password_temp[ m_byte++ ] = m_shift; + verboselog( 1, "-> program configuration password[%d]: %02x\n", m_byte, m_shift ); + m_password_temp[m_byte++] = m_shift; if( m_byte == sizeof( m_password_temp ) ) { - if( memcmp( &m_password_temp[ 0 ], &m_password_temp[ 8 ], sizeof( m_configuration_password ) ) == 0 ) + if( memcmp( &m_password_temp[0], &m_password_temp[8], sizeof( m_configuration_password ) ) == 0 ) { std::copy_n( std::begin( m_password_temp ), sizeof( m_configuration_password ), std::begin ( m_configuration_password ) ); } @@ -611,14 +614,14 @@ void x76f041_device::write_scl(int state) { case STATE_READ_DATA: offset = data_offset(); - m_shift = m_data[ offset ]; - verboselog( 1, "<- data[ %03x ]: %02x\n", offset, m_shift ); + m_shift = m_data[offset]; + verboselog( 1, "<- data[%03x]: %02x\n", offset, m_shift ); break; case STATE_READ_CONFIGURATION_REGISTERS: offset = m_byte & 7; - m_shift = m_configuration_registers[ offset ]; - verboselog( 1, "<- configuration register[ %d ]: %02x\n", offset, m_shift ); + m_shift = m_configuration_registers[offset]; + verboselog( 1, "<- configuration register[%d]: %02x\n", offset, m_shift ); break; } } @@ -676,7 +679,7 @@ void x76f041_device::write_sda(int state) break; case STATE_LOAD_PASSWORD: - /* todo: this will be the 0xc0 command, but it's not handled as a command yet. */ + /* TODO: this will be the 0xc0 command, but it's not handled as a command yet. */ verboselog( 1, "goto start\n" ); break; @@ -751,24 +754,54 @@ void x76f041_device::nvram_default() bool x76f041_device::nvram_read( util::read_stream &file ) { + std::error_condition err; size_t actual; - bool result = !file.read( m_response_to_reset, sizeof( m_response_to_reset ), actual ) && actual == sizeof( m_response_to_reset ); - result = result && !file.read( m_write_password, sizeof( m_write_password ), actual ) && actual == sizeof( m_write_password ); - result = result && !file.read( m_read_password, sizeof( m_read_password ), actual ) && actual == sizeof( m_read_password ); - result = result && !file.read( m_configuration_password, sizeof( m_configuration_password ), actual ) && actual == sizeof( m_configuration_password ); - result = result && !file.read( m_configuration_registers, sizeof( m_configuration_registers ), actual ) && actual == sizeof( m_configuration_registers ); - result = result && !file.read( m_data, sizeof( m_data ), actual ) && actual == sizeof( m_data ); - return result; + + std::tie( err, actual ) = read( file, m_response_to_reset, sizeof( m_response_to_reset ) ); + if( err || ( sizeof( m_response_to_reset ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_write_password, sizeof( m_write_password ) ); + if( err || ( sizeof( m_write_password ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_read_password, sizeof( m_read_password ) ); + if( err || ( sizeof( m_read_password ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_configuration_password, sizeof( m_configuration_password ) ); + if( err || ( sizeof( m_configuration_password ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_configuration_registers, sizeof( m_configuration_registers ) ); + if( err || ( sizeof( m_configuration_registers ) != actual ) ) + return false; + std::tie( err, actual ) = read( file, m_data, sizeof( m_data ) ); + if( err || ( sizeof( m_data ) != actual ) ) + return false; + + return true; } bool x76f041_device::nvram_write( util::write_stream &file ) { + std::error_condition err; size_t actual; - bool result = !file.write( m_response_to_reset, sizeof( m_response_to_reset ), actual ) && actual == sizeof( m_response_to_reset ); - result = result && !file.write( m_write_password, sizeof( m_write_password ), actual ) && actual == sizeof( m_write_password ); - result = result && !file.write( m_read_password, sizeof( m_read_password ), actual ) && actual == sizeof( m_read_password ); - result = result && !file.write( m_configuration_password, sizeof( m_configuration_password ), actual ) && actual == sizeof( m_configuration_password ); - result = result && !file.write( m_configuration_registers, sizeof( m_configuration_registers ), actual ) && actual == sizeof( m_configuration_registers ); - result = result && !file.write( m_data, sizeof( m_data ), actual ) && actual == sizeof( m_data ); - return result; + + std::tie( err, actual ) = write( file, m_response_to_reset, sizeof( m_response_to_reset ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_write_password, sizeof( m_write_password ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_read_password, sizeof( m_read_password ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_configuration_password, sizeof( m_configuration_password ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_configuration_registers, sizeof( m_configuration_registers ) ); + if (err) + return false; + std::tie( err, actual ) = write( file, m_data, sizeof( m_data ) ); + if (err) + return false; + + return true; } |