Huhu, hatte mal angefangen einen Emulator zu schreiben für die AT90SC72er, das meiste ist geschrieben.
Da fehlt aber noch mehr. Wer mag hier der Source als open Source:
Da fehlt aber noch mehr. Wer mag hier der Source als open Source:
Code:
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Random import get_random_bytes
class AT90SC7272Emulator:
def __init__(self):
# Initialize special function registers (SFRs) with address mappings
self.sfr = {
# Status Registers
'SREG': 0x005F, # Status Register
'SPH': 0x005E, # Stack Pointer High Byte
'SPL': 0x005D, # Stack Pointer Low Byte
# Timer/Counter Registers
'TCCR0': 0x0053, # Timer/Counter Control Register 0
'TCNT0': 0x0052, # Timer/Counter Register 0
'OCR0': 0x0051, # Output Compare Register 0
# I/O Registers
'PORTA': 0x002B, # Port A Data Register
'DDRA': 0x002A, # Port A Data Direction Register
'PINA': 0x0029, # Port A Input Pins Address
'PORTB': 0x0025, # Port B Data Register
'DDRB': 0x0024, # Port B Data Direction Register
'PINB': 0x0023, # Port B Input Pins Address
# Crypto and RSA Registers
'CRYPCTRL': 0x00, # Crypto Control Register
'CRYPDATA': 0x00, # Crypto Data Register
'CRYPSTAT': 0x00, # Crypto Status Register
'DESCTRL': 0x00, # DES Control Register
'DESDATA': 0x00, # DES Data Register
'DESKEYMASK': 0x00, # DES Key Mask Register
'RSACTRL': 0x00, # RSA Control Register
'RSADATA': 0x00, # RSA Data Register
'RSAKEY': 0x00, # RSA Key Register
# Add more peripheral and I/O registers as needed
}
# Initialize memory and other components
self.io_registers = [0] * 0x60 # General I/O registers
self.ext_io_registers = [0] * 0x20 # Extended I/O registers
self.ram = [0] * 0x800 # Internal SRAM
self.eeprom = [0] * 0x200 # EEPROM
self.flash = [0] * 0x8000 # Flash memory
self.stack_pointer = 0x05FF # Assuming stack starts at the top of RAM
self.pc = 0 # Program Counter
self.cycles = 0 # Cycle counter
# Supervisor and User Modes
self.current_mode = 'USER' # Start in User mode by default
# RAM Sharing
self.shared_ram_start = 0x0400 # Example start of shared RAM region
self.shared_ram_end = 0x05FF # Example end of shared RAM region
def load_program(self, program, address=0x0000):
"""Load a program into Flash memory."""
if len(program) > len(self.flash):
raise ValueError("Program size exceeds Flash memory capacity")
self.flash[address:address+len(program)] = program
def load_data_to_eeprom(self, data, address=0x0000):
"""Load data into EEPROM."""
if len(data) > len(self.eeprom):
raise ValueError("Data size exceeds EEPROM capacity")
self.eeprom[address:address+len(data)] = data
def read_memory(self, address):
"""Read from memory based on the address."""
if address in self.sfr:
return self.sfr[address]
elif self.IO_START <= address < self.IO_START + len(self.io_registers):
return self.io_registers[address - self.IO_START]
elif self.EXT_IO_START <= address < self.EXT_IO_START + len(self.ext_io_registers):
return self.ext_io_registers[address - self.EXT_IO_START]
elif self.RAM_START <= address < self.RAM_START + len(self.ram):
return self.ram[address - self.RAM_START]
elif self.EEPROM_START <= address < self.EEPROM_START + len(self.eeprom):
return self.eeprom[address - self.EEPROM_START]
elif self.FLASH_START <= address < self.FLASH_START + len(self.flash):
return self.flash[address - self.FLASH_START]
else:
raise ValueError("Memory read out of bounds")
def write_memory(self, address, value):
"""Write to memory based on the address."""
if self.current_mode == 'USER' and self.is_protected_memory(address):
raise PermissionError("Access denied in User mode")
if address in self.sfr:
self.sfr[address] = value
if address == 'TCCR0':
self.update_timer(value)
elif address == 'SMCR':
self.switch_to_supervisor_mode()
elif address == 'UMCR':
self.switch_to_user_mode()
elif address == 'DESCTRL':
self.update_des(value)
elif address == 'DESKEYMASK':
self.update_des_key_mask(value)
elif address == 'RSACTRL':
self.update_rsa(value)
elif self.IO_START <= address < self.IO_START + len(self.io_registers):
self.io_registers[address - self.IO_START] = value
elif self.EXT_IO_START <= address < self.EXT_IO_START + len(self.ext_io_registers):
self.ext_io_registers[address - self.EXT_IO_START] = value
elif self.RAM_START <= address < self.RAM_START + len(self.ram):
self.ram[address - self.RAM_START] = value
elif self.EEPROM_START <= address < self.EEPROM_START + len(self.eeprom):
self.eeprom[address - self.EEPROM_START] = value
elif self.FLASH_START <= address < self.FLASH_START + len(self.flash):
self.flash[address - self.FLASH_START] = value
else:
raise ValueError("Memory write out of bounds")
def update_timer(self, value):
"""Update the timer based on the TCCR0 register value."""
if value & 0x01: # If the timer is enabled
self.timer_running = True
self.timer_value = 0
else:
self.timer_running = False
def update_des(self, value):
"""Update the DES Control Register and handle DES encryption/decryption."""
self.sfr['DESCTRL'] = value
if value & 0x01: # Example: Start DES encryption/decryption if the LSB is set
self.perform_des_operation()
def update_des_key_mask(self, value):
"""Update the DES Key Mask Register."""
self.sfr['DESKEYMASK'] = value
# Implement any logic needed to apply the key mask to the DES operation
pass
def perform_des_operation(self):
"""Perform DES encryption or decryption based on the DES Control Register."""
# Placeholder for actual DES logic
# You would implement the DES algorithm or connect to a DES library here
self.sfr['DESDATA'] = 0xDEADBEEF # Example output after DES operation
def update_rsa(self, value):
"""Update the RSA Control Register and handle RSA operations."""
self.sfr['RSACTRL'] = value
if value & 0x01: # Start RSA operation if LSB is set
self.perform_rsa_operation()
def perform_rsa_operation(self):
"""Perform RSA encryption or decryption based on the RSA Control Register."""
rsa_key = RSA.import_key(self.sfr['RSAKEY'])
cipher_rsa = PKCS1_OAEP.new(rsa_key)
if self.sfr['RSACTRL'] & 0x02: # Example: Encrypt if bit 1 is set
ciphertext = cipher_rsa.encrypt(self.sfr['RSADATA'].to_bytes(128, 'big'))
self.sfr['RSADATA'] = int.from_bytes(ciphertext, 'big')
elif self.sfr['RSACTRL'] & 0x04: # Example: Decrypt if bit 2 is set
plaintext = cipher_rsa.decrypt(self.sfr['RSADATA'].to_bytes(128, 'big'))
self.sfr['RSADATA'] = int.from_bytes(plaintext, 'big')
def switch_to_supervisor_mode(self):
"""Switch to Supervisor mode."""
self.current_mode = 'SUPERVISOR'
self.sfr['SMCR'] = 0x01 # Set Supervisor mode bit
self.sfr['UMCR'] = 0x00 # Clear User mode bit
def switch_to_user_mode(self):
"""Switch to User mode."""
self.current_mode = 'USER'
self.sfr['SMCR'] = 0x00 # Clear Supervisor mode bit
self.sfr['UMCR'] = 0x01 # Set User mode bit
def is_protected_memory(self, address):
"""Check if the address is in a protected memory region."""
protected_regions = [
(self.FLASH_START, self.FLASH_START + len(self.flash)),
# Add more protected regions if needed
]
return any(start <= address < end for start, end in protected_regions)
def is_accessible_ram(self, address):
"""Check if the RAM address is accessible based on the current mode."""
if self.current_mode == 'SUPERVISOR':
return True # Supervisor mode can access all RAM
# User mode can only access shared RAM regions
return self.shared_ram_start <= address <= self.shared_ram_end
def check_security_violation(self, address, value):
"""Check for security violations."""
# Example logic to set the SVR (Security Violation Register) on certain conditions
if self.is_protected_memory(address) and not self.is_authorized(address, value):
self.sfr['SVR'] |= 0x01 # Set security violation bit
def is_authorized(self, address, value):
"""Check if the access to the given address is authorized."""
# Implement logic to verify if the current operation is authorized
return True # Placeholder logic, return actual check result
def fetch(self):
"""Fetch the next instruction from Flash memory."""
instruction = self.read_memory(self.pc)
self.pc += 1
return instruction
def decode(self, instruction):
"""Decode the instruction."""
# Implement instruction decoding based on opcode
return instruction
def execute(self, decoded_instruction):
"""Execute the instruction."""
# Execute based on the decoded instruction type
self.cycles += self.get_instruction_cycles(decoded_instruction)
self.check_security_violation(self.pc, decoded_instruction)
self.increment_timer() # Increment the timer on each cycle
self.handle_interrupts() # Check for interrupts
def get_instruction_cycles(self, instruction):
"""Determine the number of cycles an instruction takes."""
# Example: A simple lookup or switch-case based on instruction type
cycles = {
# Opcode: cycle count
0x00: 1, # NOP (No operation)
0x01: 2, # Example instruction
# Add more instructions and their cycle counts here
}
return cycles.get(instruction, 1) # Default to 1 cycle if not found
def no_op(self):
"""No operation - used as a placeholder for unassigned interrupts."""
pass
def increment_timer(self):
"""Increment the timer and handle overflow."""
if hasattr(self, 'timer_running') and self.timer_running:
self.timer_value += 1
if self.timer_value > 0xFF: # 8-bit timer overflow
self.timer_value = 0
self.sfr['TIFR'] |= 0x01 # Set the overflow flag
if self.sfr['TIMSK'] & 0x01:
self.trigger_interrupt(1) # Trigger timer overflow interrupt
def trigger_interrupt(self, interrupt_number):
"""Trigger an interrupt."""
if self.sfr['SREG'] & 0x80: # Check if global interrupts are enabled
self.interrupt_pending = True
self.current_interrupt = interrupt_number
self.sfr['INTRQ'] |= (1 << interrupt_number) # Set the interrupt request flag
def handle_interrupts(self):
"""Handle any pending interrupts."""
if hasattr(self, 'interrupt_pending') and self.interrupt_pending:
self.interrupt_pending = False
self.interrupt_vector[self.current_interrupt]() # Call the ISR
self.sfr['GIFR'] &= ~(1 << self.current_interrupt) # Clear the interrupt flag
def push_to_stack(self, value):
"""Push a value onto the stack."""
self.write_memory(self.stack_pointer, value)
self.stack_pointer -= 1 # Decrement stack pointer (assuming descending stack)
def pop_from_stack(self):
"""Pop a value from the stack."""
self.stack_pointer += 1 # Increment stack pointer (assuming descending stack)
return self.read_memory(self.stack_pointer)
def run(self):
"""Main execution loop."""
while True:
instruction = self.fetch()
decoded_instruction = self.decode(instruction)
self.execute(decoded_instruction)
# Handle interrupts, timers, etc.
# Example of loading and running a program
emulator = AT90SC7272Emulator()
program = [...] # Example binary program
emulator.load_program(program)
emulator.run()
Zuletzt bearbeitet von einem Moderator: