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)