Files
amlogic/source/bootrom_emulator/amlogic_devices.py
Eljakim Herrewijnen 0980476603 initial
2024-03-30 21:13:26 +01:00

256 lines
9.2 KiB
Python

from tools import *
class AmlogicDevice:
BASE = None
SIZE = None
def __init__(self, em):
self.em = em
def read(self, address, size):
raise Exception('must be implemented')
def write(self, address, size, value):
raise Exception('must be implemented')
# //========================================================================
# // EFUSE
# //========================================================================
# // APB4_DECODER_NON_SECURE_BASE 32'hFF630000
# // APB4_DECODER_SECURE_BASE 32'hFF630000
class EfuseDevice(AmlogicDevice):
# 0xff630000|0xff631fff|efuse
BASE = 0xff630000
SIZE = 0x2000
NAME = "efuse"
EFUSE_CLR = (BASE + (0x000 << 2))
EFUSE_START = (BASE + (0x001 << 2))
EFUSE_WDATA0 = (BASE + (0x004 << 2))
EFUSE_WDATA1 = (BASE + (0x005 << 2))
EFUSE_WDATA2 = (BASE + (0x006 << 2))
EFUSE_WDATA3 = (BASE + (0x007 << 2))
EFUSE_RDATA0 = (BASE + (0x008 << 2))
EFUSE_RDATA1 = (BASE + (0x009 << 2))
EFUSE_RDATA2 = (BASE + (0x00a << 2))
EFUSE_RDATA3 = (BASE + (0x00b << 2))
EFUSE_LIC0 = (BASE + (0x00c << 2)) # 0xff630030
EFUSE_LIC1 = (BASE + (0x00d << 2)) # 0xff630034
EFUSE_LIC2 = (BASE + (0x00e << 2))
EFUSE_LIC3 = (BASE + (0x00f << 2))
KL_START0 = (BASE + (0x020 << 2))
KL_START1 = (BASE + (0x021 << 2))
KL_RESP0_0 = (BASE + (0x024 << 2))
KL_RESP0_1 = (BASE + (0x025 << 2))
KL_RESP0_2 = (BASE + (0x026 << 2))
KL_RESP0_3 = (BASE + (0x027 << 2))
KL_RESP1_0 = (BASE + (0x028 << 2))
KL_RESP1_1 = (BASE + (0x029 << 2))
KL_RESP1_2 = (BASE + (0x02a << 2))
KL_RESP1_3 = (BASE + (0x02b << 2))
KL_RAM = (BASE + (0x040 << 2))
RNG_SEC_CONFIG_REG1 = (BASE + (0x081 << 2))
RNG_SEC_CONFIG_REG2 = (BASE + (0x082 << 2))
RNG_SEC_DATA = (BASE + (0x084 << 2))
RNG_SEC_STS = (BASE + (0x085 << 2)) #0xff630214
RNG_USR_DATA = (BASE + (0x086 << 2))
RNG_USR_STS = (BASE + (0x087 << 2))
EFUSE_RDY = BASE + 0x214
def __init__(self, em):
super().__init__(em)
def read(self, address, size):
if address == EfuseDevice.EFUSE_RDY:
self.em.write_ptr(EfuseDevice.EFUSE_RDY, 0x1)
def write(self, address, size, value):
self.em.write_ptr(address, value)
class UARTDevice(AmlogicDevice):
BASE = 0xff803000
SIZE = 0x1000
NAME = "UART"
UART_WFIFO = BASE + (0<<2)
UART_RFIFO = BASE + (1<<2)
UART_MODE = BASE + (2<<2)
UART_STATUS = BASE + (3<<2)
UART_IRQCTL = BASE + (4<<2)
UART_CTRL = BASE + (5<<2)
UART_MODE_MASK_STP_1BIT =(0<<16)
UART_MODE_MASK_CHAR_8BIT =(0<<20)
UART_MODE_MASK_TX_EN =(1<<12)
UART_MODE_MASK_RX_EN =(1<<13)
UART_STAT_MASK_RFIFO_FULL = (1<<19)
UART_STAT_MASK_RFIFO_EMPTY = (1<<20)
UART_STAT_MASK_TFIFO_FULL =(1<<21)
UART_STAT_MASK_TFIFO_EMPTY =(1<<22)
UART_MODE_MASK_RST_TX =(1<<22)
UART_MODE_MASK_RST_RX =(1<<23)
UART_MODE_MASK_CLR_ERR =(1<<24)
UART_CTRL_USE_XTAL_CLK =BASE + (1<<24)
UART_CTRL_USE_NEW_BAUD_RATE =BASE + (1<<23)
def __init__(self, em):
super().__init__(em)
self.send_data = bytearray()
self.recv_data = bytearray()
self.gsc_ring_buffer_size = 0x1000
def uart_tx_isfull(self):
return self.em.mem_read(self.BASE + self.UART_STATUS) & self.UART_STAT_MASK_TFIFO_FULL
def uart_rx_isfull(self):
return self.em.mem_read(self.BASE + self.UART_STATUS) & self.UART_STAT_MASK_RFIFO_FULL
def uart_tx_flush(self):
#TODO
# while (!(readl(P_UART_STATUS(UART_PORT_CONS)) & UART_STAT_MASK_TFIFO_EMPTY))
# ;
pass
def uart_rx_flush():
#TODO
# while (!(readl(P_UART_STATUS(UART_PORT_CONS)) & UART_STAT_MASK_RFIFO_EMPTY))
# ;
pass
def read(self, address, size):
if address == UARTDevice.UART_STATUS:
if len(self.send_data) != 0 and self.gsc_ring_buffer_size != 0:
val = self.em.read_ptr(UARTDevice.UART_STATUS) & ~UARTDevice.UART_STAT_MASK_TFIFO_EMPTY
self.em.write_ptr(UARTDevice.UART_STATUS, val)
else:
val = self.em.read_ptr(UARTDevice.UART_STATUS) | UARTDevice.UART_STAT_MASK_TFIFO_EMPTY
self.em.write_ptr(UARTDevice.UART_STATUS, val)
if address == UARTDevice.UART_RFIFO:
self.gsc_ring_buffer_size -= 1
byte = self.send_data.pop(0)
self.em.write_ptr(UARTDevice.UART_RFIFO, byte)
def write(self, address, size, value):
if address == UARTDevice.UART_WFIFO:
self.recv_data.append(value & 0xff)
else:
self.em.write_ptr(address, value)
def has_tx(self):
return len(self.send_data) != 0
def put_tx(self, data):
self.send_data.extend(data)
def has_rx(self):
return len(self.recv_data) != 0
def get_rx(self):
ret = self.recv_data
self.recv_data = bytearray()
return ret
class TimerDevice(AmlogicDevice):
# https://github.com/hardkernel/u-boot/blob/154ddfc826e72c902232169b676b2a4e59c75171/board/hardkernel/odroidn2/firmware/timing.c#L456
BASE = 0xffd0f000
SIZE = 0x1000
NAME = "isa_timer"
TIMER_CURRENT_TIME = BASE + 0x188
def __init__(self, em):
super().__init__(em)
TIMER_CURRENT_TIME2 = BASE + 0x1C
TIMER_END_TIME = BASE + 0x38
TIMER_WAIT_TIME = BASE + 0x40
def read(self, address, size):
if address == TimerDevice.TIMER_CURRENT_TIME:
val = int(time.clock_gettime_ns(0)/1000) & 0xffffffff
self.em.write_ptr(TimerDevice.TIMER_CURRENT_TIME, val)
def write(self, address, size, data):
self.em.write_ptr(address, data)
class GPIODevice(AmlogicDevice):
#define P_PIN_MUX_REG3 (*((volatile unsigned *)(0xff634400 + (0x2f << 2))))
#define P_PIN_MUX_REG4 (*((volatile unsigned *)(0xff634400 + (0x30 << 2))))
#define P_PIN_MUX_REG10 (*((volatile unsigned *)(0xff634400 + (0x36 << 2))))
BASE = 0xff634400
SIZE = 0x1000
NAME = "GPIO"
P_PIN_MUX_REG3 = BASE + (0x2f << 2)
P_PIN_MUX_REG4 = BASE + (0x30 << 2)
P_PIN_MUX_REG10 = BASE + (0x36 << 2)
def __init__(self, em):
super().__init__(em)
self.logger = setup_logger("GPIODevice")
self.logger.setLevel(logging.INFO)
def read(self, address, size):
gpio_offset = ((address - GPIODevice.BASE) // 4)
self.logger.debug(f'[{hex(self.em.pc)}]|Reading from GPIO {gpio_offset}')
def write(self, address, size, value):
gpio_offset = ((address - GPIODevice.BASE) // 4)
self.logger.debug(f'[{hex(self.em.pc)}] | Writing to GPIO {gpio_offset} Address: {hex(address)} Value: {value} Size: {size}')
self.em.write_ptr(address, value)
class USBPHYDevice(AmlogicDevice):
NAME = "USBPHY"
NAME2 = "usbphy21"
BASE = 0xff63a000
SIZE = 0x2000
def __init__(self, em):
super().__init__(em)
def read(self, address, size):
pass
def write(self, address, size, value):
self.em.write_ptr(address, value)
class USB1Device(AmlogicDevice):
NAME = "USB1"
NAME2 = "usbphy21"
BASE = 0xff400000
SIZE = 1 * MB
def __init__(self, em):
super().__init__(em)
self.logger = setup_logger("USB1")
self.logger.setLevel(logging.DEBUG)
def read(self, address, size):
self.logger.debug(f"Address: {hex(address)} size:{hex(size)}")
if address == 0xff400040:
# self.em.write_ptr(address, 0x4f543fff)
# self.em.write_ptr(address, 1)
pass
elif address == 0xff400014 or address == 0xff400018 or address == 0xff400004:
# self.em.write_ptr(address, 1)
pass
def write(self, address, size, value):
self.em.write_ptr(address, value)
class WatchdogDevice(AmlogicDevice):
# TODO??
def __init__(self, em):
super().__init__(em)