Loading py393sata/x393_mem.py +47 −19 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ class X393Mem(object): MAXI0_BASE=0x40000000 MAXI1_BASE=0x80000000 MAXI_BASE = MAXI0_BASE USE_NEGATIVE = True # Old versions of Python (2.7.3) required mmap offset to fit into 32 bits, so upper half had to be negative # 2.7.11 does not need subtraction(and reports error if negative) def __init__(self, debug_mode=1,dry_mode=False, maxi_port=0): if maxi_port: Loading @@ -65,6 +67,26 @@ class X393Mem(object): maxi_port = (0,1)[self.MAXI_BASE == self.MAXI1_BASE] print ("MAXI port = %d (0x%08x)"%(maxi_port, self.MAXI_BASE)) def wrap_mm (self, f, page_addr): if page_addr>=0x80000000: if (self.USE_NEGATIVE): try: return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr - (1<<32)) except: self.USE_NEGATIVE = False print ("Turning OFF use of negative offsets in mmap") return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr) else: try: return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr) except: print ("Turning ON use of negative offsets in mmap") self.USE_NEGATIVE = True return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr - (1<<32)) else: return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr) def write_mem (self,addr, data,quiet=1): """ Write 32-bit word to physical memory Loading @@ -78,9 +100,10 @@ class X393Mem(object): with open("/dev/mem", "r+b") as f: page_addr=addr & (~(self.PAGE_SIZE-1)) page_offs=addr-page_addr if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) packedData=struct.pack(self.ENDIAN+"L",data) d=struct.unpack(self.ENDIAN+"L",packedData)[0] mm[page_offs:page_offs+4]=packedData Loading Loading @@ -108,9 +131,10 @@ class X393Mem(object): with open("/dev/mem", "r+b") as f: page_addr=addr & (~(self.PAGE_SIZE-1)) page_offs=addr-page_addr if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) data=struct.unpack(self.ENDIAN+"L",mm[page_offs:page_offs+4]) d=data[0] if quiet < 1: Loading Loading @@ -149,9 +173,10 @@ class X393Mem(object): for addr in range (start_addr,end_addr+byte_mode,byte_mode): page_addr=addr & (~(self.PAGE_SIZE-1)) page_offs=addr-page_addr if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) data=struct.unpack_from(self.ENDIAN+frmt_bytes[byte_mode],mm, page_offs) rslt.append(data[0]) Loading Loading @@ -202,9 +227,10 @@ class X393Mem(object): if page_num == last_page: end_offset = start_addr + length - self.PAGE_SIZE * page_num page_addr = page_num * self.PAGE_SIZE if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) bf.write(mm[start_offset:end_offset]) def mem_clear (self, start_addr, length, word32): Loading @@ -229,9 +255,10 @@ class X393Mem(object): if page_num == last_page: end_offset = start_addr + length - self.PAGE_SIZE * page_num page_addr = page_num * self.PAGE_SIZE if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm[start_offset:end_offset] = patt[start_offset:end_offset] Loading Loading @@ -273,9 +300,10 @@ class X393Mem(object): data = (start_data + ((addr-start_addr) // byte_mode)*inc_data) & data_mask page_addr=addr & (~(self.PAGE_SIZE-1)) page_offs=addr-page_addr if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) struct.pack_into(self.ENDIAN+frmt_bytes[byte_mode],mm, page_offs, data) ''' Loading py393sata/x393_vsc3304.py +17 −2 Original line number Diff line number Diff line Loading @@ -32,9 +32,10 @@ import os from x393_mem import X393Mem #from time import sleep #import shutil VSC_DIR="/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0001" VSC_DIR_OLD="/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0001" VSC_DIR_NEW="/sys/devices/soc0/amba@0/e0004000.ps7-i2c/i2c-0/0-0001" # 10389 rev "0" VSC_DIR = None class x393_vsc3304(object): DRY_MODE= True # True DEBUG_MODE=1 Loading Loading @@ -88,17 +89,31 @@ class x393_vsc3304(object): PCB_REV = "10389" current_mode = "ESATA<->SSD" def __init__(self, debug_mode=1,dry_mode=False, pcb_rev = "10389"): global VSC_DIR self.DEBUG_MODE=debug_mode if not dry_mode: if not os.path.exists("/dev/xdevcfg"): dry_mode=True print("Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)") else: if os.path.exists(VSC_DIR_OLD): print ('x393_vsc3304: Running on OLD system') VSC_DIR = VSC_DIR_OLD elif os.path.exists(VSC_DIR_NEW): print ('x393_vsc3304: Running on NEW system') VSC_DIR = VSC_DIR_NEW else: print ("Does not seem to be a known system - both %s (old) and %s (new) are not found"%(VSC_DIR_OLD, VSC_DIR_NEW)) return self.DRY_MODE=dry_mode self.x393_mem=X393Mem(debug_mode,dry_mode, 1) if not pcb_rev in self.PCB_CONNECTIONS: print ("Unknown PCB/rev: %s (defined: %s), using %s"%(pcb_rev, str(self.PCB_CONNECTIONS.keys()),self.PCB_REV)) else: self.PCB_REV = pcb_rev def echo(self, what, where): if self.DRY_MODE: print ("'%s' -> '%s'"%(str(what), VSC_DIR+"/"+where)) Loading py393sata/x393sata.py +280 −1 Original line number Diff line number Diff line Loading @@ -37,13 +37,58 @@ from x393_vsc3304 import x393_vsc3304 import create_ahci_registers as registers from time import sleep import shutil PAGE_SIZE = 4096 #:/sys/devices/soc0/amba@0/e0004000.ps7-i2c/i2c-0 #Old System SI5338_PATH_OLD = '/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0070' MEM_PATH_OLD = '/sys/devices/elphel393-mem.2/' #new System SI5338_PATH_NEW = '/sys/devices/soc0/amba@0/e0004000.ps7-i2c/i2c-0/0-0070' MEM_PATH_NEW = '/sys/devices/soc0/elphel393-mem@0/' DEFAULT_BITFILE="/usr/local/verilog/x393_sata.bit" SI5338_PATH = '/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0070' BUFFER_ADDRESS_NAME = 'buffer_address' BUFFER_PAGES_NAME = 'buffer_pages' BUFFER_FLUSH_NAME = 'buffer_flush' FPGA_RST_CTRL= 0xf8000240 FPGA0_THR_CTRL=0xf8000178 FPGA_LOAD_BITSTREAM="/dev/xdevcfg" INT_STS= 0xf800700c MAXI1_ADDR = 0x80000000 DATASCOPE_ADDR = 0x1000 + MAXI1_ADDR COMMAND_HEADER0_OFFS = 0x800 # offset of the command header 0 in MAXI1 space COMMAND_BUFFER_OFFSET = 0x0 # Just at the beginning of available memory COMMAND_BUFFER_SIZE = 0x100 # 256 bytes - 128 before PRDT, 128+ - PRDTs (16 bytes each) PRD_OFFSET = 0x80 # Start of the PRD table DATAIN_BUFFER_OFFSET = 0x10000 DATAIN_BUFFER_SIZE = 0x10000 IDENTIFY_BUF = 0 # Identify receive buffer offset in DATAIN_BUFFER, in bytes DATAOUT_BUFFER_OFFSET = 0x20000 DATAOUT_BUFFER_SIZE = 0x10000 SI5338_PATH = None MEM_PATH = None BUFFER_ADDRESS = None # in bytes BUFFER_LEN = None # in bytes COMMAND_ADDRESS = None # start of the command buffer (to be sent to device) DATAIN_ADDRESS = None # start of the the DATAOUT_ADDRESS = None # start of the the #FIS types FIS_H2DR = 0x27 FIS_D2HR = 0x34 FIS_DMAA = 0x39 FIS_DMAS = 0x41 FIS_DATA = 0x46 FIS_BIST = 0x58 FIS_PIOS = 0x5f FIS_SDB = 0xa1 #ATA commands ATA_IDFY = 0xEC class x393sata(object): DRY_MODE= True # True DEBUG_MODE=1 Loading @@ -51,6 +96,8 @@ class x393sata(object): vsc3304 = None register_defines=None def __init__(self, debug_mode=1,dry_mode=False, pcb_rev = "10389"): global BUFFER_ADDRESS, BUFFER_LEN, COMMAND_ADDRESS, DATAIN_ADDRESS, DATAOUT_ADDRESS, SI5338_PATH, MEM_PATH self.DEBUG_MODE=debug_mode if not dry_mode: if not os.path.exists("/dev/xdevcfg"): Loading @@ -60,6 +107,40 @@ class x393sata(object): self.x393_mem=X393Mem(debug_mode,dry_mode, 1) self.vsc3304= x393_vsc3304(debug_mode, dry_mode, pcb_rev) self.register_defines = registers.process_data(False)['field_defines'] if dry_mode: BUFFER_ADDRESS=0x27900000 # 0x38100000 on new BUFFER_LEN= 0x6400000 print ("Running in simulated mode, using hard-coded addresses:") else: if os.path.exists(SI5338_PATH_OLD): print ('x393sata: Running on OLD system') SI5338_PATH = SI5338_PATH_OLD MEM_PATH = MEM_PATH_OLD elif os.path.exists(SI5338_PATH_NEW): print ('x393sata: Running on NEW system') SI5338_PATH = SI5338_PATH_NEW MEM_PATH = MEM_PATH_NEW else: print ("Does not seem to be a known system - both %s (old) and %s (new) are not found"%(SI5338_PATH_OLD, SI5338_PATH_NEW)) return try: with open(MEM_PATH+BUFFER_ADDRESS_NAME) as sysfile: BUFFER_ADDRESS=int(sysfile.read(),0) with open(MEM_PATH+BUFFER_PAGES_NAME) as sysfile: BUFFER_LEN=PAGE_SIZE*int(sysfile.read(),0) except: print("Failed to get reserved physical memory range") print('BUFFER_ADDRESS=',BUFFER_ADDRESS) print('BUFFER_LEN=',BUFFER_LEN) return COMMAND_ADDRESS = BUFFER_ADDRESS + COMMAND_BUFFER_OFFSET DATAIN_ADDRESS = BUFFER_ADDRESS + DATAIN_BUFFER_OFFSET DATAOUT_ADDRESS = BUFFER_ADDRESS + DATAOUT_BUFFER_OFFSET print('BUFFER_ADDRESS=0x%x'%(BUFFER_ADDRESS)) print('BUFFER_LEN=0x%x'%(BUFFER_LEN)) print('COMMAND_ADDRESS=0x%x'%(COMMAND_ADDRESS)) print('DATAIN_ADDRESS=0x%x'%(DATAIN_ADDRESS)) print('DATAOUT_ADDRESS=0x%x'%(DATAOUT_ADDRESS)) def reset_get(self): """ Get current reset state Loading @@ -82,6 +163,15 @@ class x393sata(object): else: for d in data: self.x393_mem.write_mem(FPGA_RST_CTRL,d) def flush_mem(self): """ Flush memory buffer """ with open (MEM_PATH+BUFFER_FLUSH_NAME,"w") as f: print ("1",file=f) def bitstream(self, bitfile=None, quiet=1): Loading Loading @@ -346,7 +436,64 @@ class x393sata(object): """ shutil.copy2(src, dst) def setup_pio_read_identify_command(self, prd_irqs = None): """ @param prd_irqs - None or a tuple/list with per-PRD interrupts """ # clear system memory for command for a in range(64): self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0) self.x393_mem.write_mem(COMMAND_ADDRESS + 0, FIS_H2DR | # FIS type - H2D register (0x27) (0x80 << 8) | # set C = 1 (ATA_IDFY << 16) | # Command = 0xEC (IDFY) ( 0 << 24)) # features = 0 ? # All other 4 DWORDs are 0 for this command # Set PRDT (single item) TODO: later check multiple small ones self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + (0 << 2), DATAIN_ADDRESS + IDENTIFY_BUF) prdt_int = 0 if prd_irqs: prdt_int = (0,1)[prd_irqs[0]] self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + (3 << 2), DATAIN_ADDRESS + (prdt_int << 31) | 511) # 512 bytes in this PRDT) # Setup command header self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (0 << 2), (5 << 0) | # 'CFL' - number of DWORDs in this CFIS (0 << 5) | # 'A' Not ATAPI (0 << 6) | # 'W' Not write to device (1 << 7) | # 'P' Prefetchable = 1 (0 << 8) | # 'R' Not a Reset (0 << 9) | # 'B' Not a BIST (1 << 10) | # 'C' Do clear BSY/CI after transmitting this command (1 << 16)) # 'PRDTL' - number of PRDT entries (just one) self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (2 << 2), (COMMAND_ADDRESS) & 0xffffffc0) # 'CTBA' - Command table base address # Make it flush? # Write some junk to the higher addresses of the CFIS for i in range (10): self.x393_mem.write_mem(COMMAND_ADDRESS + 4*(i+1), (4 * i + 1) | ((4 * i + 2) << 8) | ((4 * i + 3) << 16) | ((4 * i + 4) << 24)) for i in range (4066): self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i)) # print("Running flush_mem()") # self.flush_mem() # Set Command Issued #self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCI'), 1) print("_=mem.mem_dump (0x%x, 0x20,4)"%(COMMAND_ADDRESS)) self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4) print("_=mem.mem_dump (0x%x, 0x20,4)"%(DATASCOPE_ADDR)) self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x20,4) print("mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1)") """ mem.write_mem(0x80000118,0x11) # ST & FRE cd /mnt/mmc/local/bin python from __future__ import print_function Loading @@ -356,6 +503,15 @@ import x393_mem mem = x393_mem.X393Mem(1,0,1) sata = x393sata.x393sata() sata.bitstream() sata.reg_status() mem.write_mem(0x80000118,0x11) sata.setup_pio_read_identify_command() mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1) _=mem.mem_dump (0x80001000, 0x20,4) sata.vsc3304.connection_status() sata.reg_status() Loading @@ -367,11 +523,134 @@ hex(mem.read_mem(0x8000012c)) hex(mem.read_mem(0x80000130)) hex(mem.read_mem(0x80000ff0)) sata.reset_ie(), sata.reg_status() hex(mem.read_mem(0x80000ff0)) mem.write_mem(0x80000118,0x11) sata.setup_pio_read_identify_command() mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1) _=mem.mem_dump (0x80001000, 0x20,4) mem.maxi_base() hex(mem.read_mem(0x80000180)) mem.mem_dump (0x80000000, 0x200,1) _=mem.mem_dump (0x80000000, 0x100,4) sata.reset_ie(),sata.reset_device(), sata.reg_status(), hex(mem.read_mem(0x80000ff0)) sata.reset_ie(), sata.reg_status(), hex(mem.read_mem(0x80000ff0)) _=mem.mem_dump (0x80001000, 0x10,4) _=mem.mem_dump (0x80001000, 0x20,4) _=mem.mem_dump (0x27900000, 0x20,4) for i in range (1024): mem.write_mem(0x27900000 + 32*i, mem.read_mem(0x27900000 + 32*i)) 0x6b 16d53 06b: 00104 # CFIS:Xmit: do SET_BSY 06c: 30060 # do CFIS_XMIT, WAIT DONE ***** Got stuck here? 06d: 19039 # if X_RDY_COLLISION goto P:Idle 06e: 150f8 # if SYNCESC_ERR goto ERR:SyncEscapeRecv 06f: 0a471 # if FIS_OK goto CFIS:Success 070: 00102 # always goto ERR:Non-Fatal sata.reset_ie(),sata.reset_device(), sata.reg_status(), hex(mem.read_mem(0x80000ff0)) sata.reset_ie(), sata.reg_status(), hex(mem.read_mem(0x80000ff0)) mem.write_mem(0x80000118,0x11) sata.reg_status() mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1) _=mem.mem_dump (0x80001000, 0x20,4) mem.write_mem(0x80000118,0x10) >>> sata.setup_pio_read_identify_command() >>> sata.reg_status() HBA_PORT__PxIS: 0x00400042 [80000110] 1 : PRCS (PhyRdy changed Status) 1 : PCS (Port Connect Change Status) 1 : PSS (PIO Setup FIS Interrupt - PIO Setup FIS received with 'I' bit set) HBA_PORT__PxCMD: 0x00048017 [80000118] 1 : HPCP (Hot Plug Capable Port) 1 : CR (Command List Running (section 5.3.2)) 1 : FRE (FIS Receive Enable (enable after FIS memory is set)) 1 : POD (Power On Device (RW with Cold Presence Detection)) 1 : SUD (Spin-Up Device (RW with Staggered Spin-Up Support)) 1 : ST (Start (HBA may process commands). See section 10.3.1) HBA_PORT__PxTFD: 0x00000050 [80000120] 5 : STS.64 (Latest Copy of Task File Status Register: command-specific bits 4..6 ) HBA_PORT__PxSIG: 0x00000101 [80000124] 101 : SIG (Data in the first D2H Register FIS) HBA_PORT__PxSSTS: 0x00000123 [80000128] 1 : IPM (Interface Power Management) 2 : SPD (Interface Speed) 3 : DET (Device Detection (should be detected if COMINIT is received)) HBA_PORT__PxSERR: 0x040d0000 [80000130] 1 : DIAG.X (Exchanged (set on COMINIT), reflected in PxIS.PCS) 1 : DIAG.B (10B to 8B decode error) 1 : DIAG.W (COMMWAKE signal was detected) 1 : DIAG.N (PhyRdy changed. Reflected in PxIS.PRCS bit.) HBA_PORT__PxCI: 0x00000000 [80000138] >>> hex(mem.read_mem(0x80000ff0)) '0x3916f53' >>> _=mem.mem_dump (0x38110000, 0x100,4) 0x38110000:3fff0040 0010c837 00000000 0000003f 00000000 33393133 34303535 33353030 20202020 20202020 00000000 58320000 32303331 53613020 69736e44 53446b20 0x38110040:46313653 32384d31 20204720 20202020 20202020 20202020 20202020 80012020 2f004000 02004000 00070000 00103fff fc10003f 010100fb 0ee7c2b0 00070000 0x38110080:00780003 00780078 40200078 00000000 00000000 001f0000 0084870e 0040014c 002801f0 7d09346b 34694123 4123bc09 0001207f 00800006 0000fffe 00000000 0x381100c0:00000000 00000000 0ee7c2b0 00000000 00100000 00004000 b44a5001 2d633bf2 00000000 00000000 00000000 401c0000 0000401c 00000000 00000000 00000000 0x38110100:00000021 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110140:00000000 00000000 00000000 00000000 0001000b 00000000 00000000 00000000 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 0x38110180:20202020 20202020 20202020 20202020 20202020 20202020 20202020 00000000 40000000 00000000 00000000 00000000 00010000 00000000 00000000 0000103f 0x381101c0:00000000 00000000 00000000 00000000 00000000 00800001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4da50000 0x38110200:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110240:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110280:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x381102c0:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110300:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110340:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110380:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x381103c0:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x27900000:00ec8027 04030201 08070605 0c0b0a09 100f0e0d 14131211 18171615 1c1b1a19 201f1e1d 24232221 28272625 00000000 00000000 00000000 00000000 00000000 0x27900040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:00000000 00000000 00000000 00ec8027 04030201 08070605 0c0b0a09 100f0e0d 14131211 18171615 1c1b1a19 201f1e1d 24232221 28272625 00000000 00000000 0x80001040:00000000 00000000 00000000 00000000 00000014 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:40000000 40100000 40200000 403c8027 40430201 40570605 406b0a09 407f0e0d 40831211 40971615 40ab1a19 40bf1e1d 40c32221 40d72625 00e00000 00f00000 0x80001040:01000000 81100000 00000012 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:40000000 40100000 40200000 403c8027 40430201 40570605 406b0a09 407f0e0d 40831211 40971615 40d32221 00e72625 00f00000 01000000 81100000 0000000f 0x80001040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x27900000:00ec8027 11111111 22222222 33333333 44444444 55555555 66666666 77777777 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x27900040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000e 00000000 0x80001040:00000000 00000000 00000012 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:00000000 00000000 00000000 00ec8027 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001040:00000000 00000000 00000012 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80000000:00240020 80000000 00000000 00000001 00010301 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80000040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80000080:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Loading Loading
py393sata/x393_mem.py +47 −19 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ class X393Mem(object): MAXI0_BASE=0x40000000 MAXI1_BASE=0x80000000 MAXI_BASE = MAXI0_BASE USE_NEGATIVE = True # Old versions of Python (2.7.3) required mmap offset to fit into 32 bits, so upper half had to be negative # 2.7.11 does not need subtraction(and reports error if negative) def __init__(self, debug_mode=1,dry_mode=False, maxi_port=0): if maxi_port: Loading @@ -65,6 +67,26 @@ class X393Mem(object): maxi_port = (0,1)[self.MAXI_BASE == self.MAXI1_BASE] print ("MAXI port = %d (0x%08x)"%(maxi_port, self.MAXI_BASE)) def wrap_mm (self, f, page_addr): if page_addr>=0x80000000: if (self.USE_NEGATIVE): try: return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr - (1<<32)) except: self.USE_NEGATIVE = False print ("Turning OFF use of negative offsets in mmap") return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr) else: try: return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr) except: print ("Turning ON use of negative offsets in mmap") self.USE_NEGATIVE = True return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr - (1<<32)) else: return mmap.mmap(f.fileno(), self.PAGE_SIZE, offset = page_addr) def write_mem (self,addr, data,quiet=1): """ Write 32-bit word to physical memory Loading @@ -78,9 +100,10 @@ class X393Mem(object): with open("/dev/mem", "r+b") as f: page_addr=addr & (~(self.PAGE_SIZE-1)) page_offs=addr-page_addr if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) packedData=struct.pack(self.ENDIAN+"L",data) d=struct.unpack(self.ENDIAN+"L",packedData)[0] mm[page_offs:page_offs+4]=packedData Loading Loading @@ -108,9 +131,10 @@ class X393Mem(object): with open("/dev/mem", "r+b") as f: page_addr=addr & (~(self.PAGE_SIZE-1)) page_offs=addr-page_addr if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) data=struct.unpack(self.ENDIAN+"L",mm[page_offs:page_offs+4]) d=data[0] if quiet < 1: Loading Loading @@ -149,9 +173,10 @@ class X393Mem(object): for addr in range (start_addr,end_addr+byte_mode,byte_mode): page_addr=addr & (~(self.PAGE_SIZE-1)) page_offs=addr-page_addr if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) data=struct.unpack_from(self.ENDIAN+frmt_bytes[byte_mode],mm, page_offs) rslt.append(data[0]) Loading Loading @@ -202,9 +227,10 @@ class X393Mem(object): if page_num == last_page: end_offset = start_addr + length - self.PAGE_SIZE * page_num page_addr = page_num * self.PAGE_SIZE if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) bf.write(mm[start_offset:end_offset]) def mem_clear (self, start_addr, length, word32): Loading @@ -229,9 +255,10 @@ class X393Mem(object): if page_num == last_page: end_offset = start_addr + length - self.PAGE_SIZE * page_num page_addr = page_num * self.PAGE_SIZE if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm[start_offset:end_offset] = patt[start_offset:end_offset] Loading Loading @@ -273,9 +300,10 @@ class X393Mem(object): data = (start_data + ((addr-start_addr) // byte_mode)*inc_data) & data_mask page_addr=addr & (~(self.PAGE_SIZE-1)) page_offs=addr-page_addr if (page_addr>=0x80000000): page_addr-= (1<<32) mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) mm = self.wrap_mm(f, page_addr) # if (page_addr>=0x80000000): # page_addr-= (1<<32) # mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr) struct.pack_into(self.ENDIAN+frmt_bytes[byte_mode],mm, page_offs, data) ''' Loading
py393sata/x393_vsc3304.py +17 −2 Original line number Diff line number Diff line Loading @@ -32,9 +32,10 @@ import os from x393_mem import X393Mem #from time import sleep #import shutil VSC_DIR="/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0001" VSC_DIR_OLD="/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0001" VSC_DIR_NEW="/sys/devices/soc0/amba@0/e0004000.ps7-i2c/i2c-0/0-0001" # 10389 rev "0" VSC_DIR = None class x393_vsc3304(object): DRY_MODE= True # True DEBUG_MODE=1 Loading Loading @@ -88,17 +89,31 @@ class x393_vsc3304(object): PCB_REV = "10389" current_mode = "ESATA<->SSD" def __init__(self, debug_mode=1,dry_mode=False, pcb_rev = "10389"): global VSC_DIR self.DEBUG_MODE=debug_mode if not dry_mode: if not os.path.exists("/dev/xdevcfg"): dry_mode=True print("Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)") else: if os.path.exists(VSC_DIR_OLD): print ('x393_vsc3304: Running on OLD system') VSC_DIR = VSC_DIR_OLD elif os.path.exists(VSC_DIR_NEW): print ('x393_vsc3304: Running on NEW system') VSC_DIR = VSC_DIR_NEW else: print ("Does not seem to be a known system - both %s (old) and %s (new) are not found"%(VSC_DIR_OLD, VSC_DIR_NEW)) return self.DRY_MODE=dry_mode self.x393_mem=X393Mem(debug_mode,dry_mode, 1) if not pcb_rev in self.PCB_CONNECTIONS: print ("Unknown PCB/rev: %s (defined: %s), using %s"%(pcb_rev, str(self.PCB_CONNECTIONS.keys()),self.PCB_REV)) else: self.PCB_REV = pcb_rev def echo(self, what, where): if self.DRY_MODE: print ("'%s' -> '%s'"%(str(what), VSC_DIR+"/"+where)) Loading
py393sata/x393sata.py +280 −1 Original line number Diff line number Diff line Loading @@ -37,13 +37,58 @@ from x393_vsc3304 import x393_vsc3304 import create_ahci_registers as registers from time import sleep import shutil PAGE_SIZE = 4096 #:/sys/devices/soc0/amba@0/e0004000.ps7-i2c/i2c-0 #Old System SI5338_PATH_OLD = '/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0070' MEM_PATH_OLD = '/sys/devices/elphel393-mem.2/' #new System SI5338_PATH_NEW = '/sys/devices/soc0/amba@0/e0004000.ps7-i2c/i2c-0/0-0070' MEM_PATH_NEW = '/sys/devices/soc0/elphel393-mem@0/' DEFAULT_BITFILE="/usr/local/verilog/x393_sata.bit" SI5338_PATH = '/sys/devices/amba.0/e0004000.ps7-i2c/i2c-0/0-0070' BUFFER_ADDRESS_NAME = 'buffer_address' BUFFER_PAGES_NAME = 'buffer_pages' BUFFER_FLUSH_NAME = 'buffer_flush' FPGA_RST_CTRL= 0xf8000240 FPGA0_THR_CTRL=0xf8000178 FPGA_LOAD_BITSTREAM="/dev/xdevcfg" INT_STS= 0xf800700c MAXI1_ADDR = 0x80000000 DATASCOPE_ADDR = 0x1000 + MAXI1_ADDR COMMAND_HEADER0_OFFS = 0x800 # offset of the command header 0 in MAXI1 space COMMAND_BUFFER_OFFSET = 0x0 # Just at the beginning of available memory COMMAND_BUFFER_SIZE = 0x100 # 256 bytes - 128 before PRDT, 128+ - PRDTs (16 bytes each) PRD_OFFSET = 0x80 # Start of the PRD table DATAIN_BUFFER_OFFSET = 0x10000 DATAIN_BUFFER_SIZE = 0x10000 IDENTIFY_BUF = 0 # Identify receive buffer offset in DATAIN_BUFFER, in bytes DATAOUT_BUFFER_OFFSET = 0x20000 DATAOUT_BUFFER_SIZE = 0x10000 SI5338_PATH = None MEM_PATH = None BUFFER_ADDRESS = None # in bytes BUFFER_LEN = None # in bytes COMMAND_ADDRESS = None # start of the command buffer (to be sent to device) DATAIN_ADDRESS = None # start of the the DATAOUT_ADDRESS = None # start of the the #FIS types FIS_H2DR = 0x27 FIS_D2HR = 0x34 FIS_DMAA = 0x39 FIS_DMAS = 0x41 FIS_DATA = 0x46 FIS_BIST = 0x58 FIS_PIOS = 0x5f FIS_SDB = 0xa1 #ATA commands ATA_IDFY = 0xEC class x393sata(object): DRY_MODE= True # True DEBUG_MODE=1 Loading @@ -51,6 +96,8 @@ class x393sata(object): vsc3304 = None register_defines=None def __init__(self, debug_mode=1,dry_mode=False, pcb_rev = "10389"): global BUFFER_ADDRESS, BUFFER_LEN, COMMAND_ADDRESS, DATAIN_ADDRESS, DATAOUT_ADDRESS, SI5338_PATH, MEM_PATH self.DEBUG_MODE=debug_mode if not dry_mode: if not os.path.exists("/dev/xdevcfg"): Loading @@ -60,6 +107,40 @@ class x393sata(object): self.x393_mem=X393Mem(debug_mode,dry_mode, 1) self.vsc3304= x393_vsc3304(debug_mode, dry_mode, pcb_rev) self.register_defines = registers.process_data(False)['field_defines'] if dry_mode: BUFFER_ADDRESS=0x27900000 # 0x38100000 on new BUFFER_LEN= 0x6400000 print ("Running in simulated mode, using hard-coded addresses:") else: if os.path.exists(SI5338_PATH_OLD): print ('x393sata: Running on OLD system') SI5338_PATH = SI5338_PATH_OLD MEM_PATH = MEM_PATH_OLD elif os.path.exists(SI5338_PATH_NEW): print ('x393sata: Running on NEW system') SI5338_PATH = SI5338_PATH_NEW MEM_PATH = MEM_PATH_NEW else: print ("Does not seem to be a known system - both %s (old) and %s (new) are not found"%(SI5338_PATH_OLD, SI5338_PATH_NEW)) return try: with open(MEM_PATH+BUFFER_ADDRESS_NAME) as sysfile: BUFFER_ADDRESS=int(sysfile.read(),0) with open(MEM_PATH+BUFFER_PAGES_NAME) as sysfile: BUFFER_LEN=PAGE_SIZE*int(sysfile.read(),0) except: print("Failed to get reserved physical memory range") print('BUFFER_ADDRESS=',BUFFER_ADDRESS) print('BUFFER_LEN=',BUFFER_LEN) return COMMAND_ADDRESS = BUFFER_ADDRESS + COMMAND_BUFFER_OFFSET DATAIN_ADDRESS = BUFFER_ADDRESS + DATAIN_BUFFER_OFFSET DATAOUT_ADDRESS = BUFFER_ADDRESS + DATAOUT_BUFFER_OFFSET print('BUFFER_ADDRESS=0x%x'%(BUFFER_ADDRESS)) print('BUFFER_LEN=0x%x'%(BUFFER_LEN)) print('COMMAND_ADDRESS=0x%x'%(COMMAND_ADDRESS)) print('DATAIN_ADDRESS=0x%x'%(DATAIN_ADDRESS)) print('DATAOUT_ADDRESS=0x%x'%(DATAOUT_ADDRESS)) def reset_get(self): """ Get current reset state Loading @@ -82,6 +163,15 @@ class x393sata(object): else: for d in data: self.x393_mem.write_mem(FPGA_RST_CTRL,d) def flush_mem(self): """ Flush memory buffer """ with open (MEM_PATH+BUFFER_FLUSH_NAME,"w") as f: print ("1",file=f) def bitstream(self, bitfile=None, quiet=1): Loading Loading @@ -346,7 +436,64 @@ class x393sata(object): """ shutil.copy2(src, dst) def setup_pio_read_identify_command(self, prd_irqs = None): """ @param prd_irqs - None or a tuple/list with per-PRD interrupts """ # clear system memory for command for a in range(64): self.x393_mem.write_mem(COMMAND_ADDRESS + 4*a, 0) self.x393_mem.write_mem(COMMAND_ADDRESS + 0, FIS_H2DR | # FIS type - H2D register (0x27) (0x80 << 8) | # set C = 1 (ATA_IDFY << 16) | # Command = 0xEC (IDFY) ( 0 << 24)) # features = 0 ? # All other 4 DWORDs are 0 for this command # Set PRDT (single item) TODO: later check multiple small ones self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + (0 << 2), DATAIN_ADDRESS + IDENTIFY_BUF) prdt_int = 0 if prd_irqs: prdt_int = (0,1)[prd_irqs[0]] self.x393_mem.write_mem(COMMAND_ADDRESS + PRD_OFFSET + (3 << 2), DATAIN_ADDRESS + (prdt_int << 31) | 511) # 512 bytes in this PRDT) # Setup command header self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (0 << 2), (5 << 0) | # 'CFL' - number of DWORDs in this CFIS (0 << 5) | # 'A' Not ATAPI (0 << 6) | # 'W' Not write to device (1 << 7) | # 'P' Prefetchable = 1 (0 << 8) | # 'R' Not a Reset (0 << 9) | # 'B' Not a BIST (1 << 10) | # 'C' Do clear BSY/CI after transmitting this command (1 << 16)) # 'PRDTL' - number of PRDT entries (just one) self.x393_mem.write_mem(MAXI1_ADDR + COMMAND_HEADER0_OFFS + (2 << 2), (COMMAND_ADDRESS) & 0xffffffc0) # 'CTBA' - Command table base address # Make it flush? # Write some junk to the higher addresses of the CFIS for i in range (10): self.x393_mem.write_mem(COMMAND_ADDRESS + 4*(i+1), (4 * i + 1) | ((4 * i + 2) << 8) | ((4 * i + 3) << 16) | ((4 * i + 4) << 24)) for i in range (4066): self.x393_mem.write_mem(COMMAND_ADDRESS + 32 * i, self.x393_mem.read_mem(COMMAND_ADDRESS + 32 * i)) # print("Running flush_mem()") # self.flush_mem() # Set Command Issued #self.x393_mem.write_mem(self.get_reg_address('HBA_PORT__PxCI'), 1) print("_=mem.mem_dump (0x%x, 0x20,4)"%(COMMAND_ADDRESS)) self.x393_mem.mem_dump (COMMAND_ADDRESS, 0x20,4) print("_=mem.mem_dump (0x%x, 0x20,4)"%(DATASCOPE_ADDR)) self.x393_mem.mem_dump (DATASCOPE_ADDR, 0x20,4) print("mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1)") """ mem.write_mem(0x80000118,0x11) # ST & FRE cd /mnt/mmc/local/bin python from __future__ import print_function Loading @@ -356,6 +503,15 @@ import x393_mem mem = x393_mem.X393Mem(1,0,1) sata = x393sata.x393sata() sata.bitstream() sata.reg_status() mem.write_mem(0x80000118,0x11) sata.setup_pio_read_identify_command() mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1) _=mem.mem_dump (0x80001000, 0x20,4) sata.vsc3304.connection_status() sata.reg_status() Loading @@ -367,11 +523,134 @@ hex(mem.read_mem(0x8000012c)) hex(mem.read_mem(0x80000130)) hex(mem.read_mem(0x80000ff0)) sata.reset_ie(), sata.reg_status() hex(mem.read_mem(0x80000ff0)) mem.write_mem(0x80000118,0x11) sata.setup_pio_read_identify_command() mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1) _=mem.mem_dump (0x80001000, 0x20,4) mem.maxi_base() hex(mem.read_mem(0x80000180)) mem.mem_dump (0x80000000, 0x200,1) _=mem.mem_dump (0x80000000, 0x100,4) sata.reset_ie(),sata.reset_device(), sata.reg_status(), hex(mem.read_mem(0x80000ff0)) sata.reset_ie(), sata.reg_status(), hex(mem.read_mem(0x80000ff0)) _=mem.mem_dump (0x80001000, 0x10,4) _=mem.mem_dump (0x80001000, 0x20,4) _=mem.mem_dump (0x27900000, 0x20,4) for i in range (1024): mem.write_mem(0x27900000 + 32*i, mem.read_mem(0x27900000 + 32*i)) 0x6b 16d53 06b: 00104 # CFIS:Xmit: do SET_BSY 06c: 30060 # do CFIS_XMIT, WAIT DONE ***** Got stuck here? 06d: 19039 # if X_RDY_COLLISION goto P:Idle 06e: 150f8 # if SYNCESC_ERR goto ERR:SyncEscapeRecv 06f: 0a471 # if FIS_OK goto CFIS:Success 070: 00102 # always goto ERR:Non-Fatal sata.reset_ie(),sata.reset_device(), sata.reg_status(), hex(mem.read_mem(0x80000ff0)) sata.reset_ie(), sata.reg_status(), hex(mem.read_mem(0x80000ff0)) mem.write_mem(0x80000118,0x11) sata.reg_status() mem.write_mem(sata.get_reg_address('HBA_PORT__PxCI'), 1) _=mem.mem_dump (0x80001000, 0x20,4) mem.write_mem(0x80000118,0x10) >>> sata.setup_pio_read_identify_command() >>> sata.reg_status() HBA_PORT__PxIS: 0x00400042 [80000110] 1 : PRCS (PhyRdy changed Status) 1 : PCS (Port Connect Change Status) 1 : PSS (PIO Setup FIS Interrupt - PIO Setup FIS received with 'I' bit set) HBA_PORT__PxCMD: 0x00048017 [80000118] 1 : HPCP (Hot Plug Capable Port) 1 : CR (Command List Running (section 5.3.2)) 1 : FRE (FIS Receive Enable (enable after FIS memory is set)) 1 : POD (Power On Device (RW with Cold Presence Detection)) 1 : SUD (Spin-Up Device (RW with Staggered Spin-Up Support)) 1 : ST (Start (HBA may process commands). See section 10.3.1) HBA_PORT__PxTFD: 0x00000050 [80000120] 5 : STS.64 (Latest Copy of Task File Status Register: command-specific bits 4..6 ) HBA_PORT__PxSIG: 0x00000101 [80000124] 101 : SIG (Data in the first D2H Register FIS) HBA_PORT__PxSSTS: 0x00000123 [80000128] 1 : IPM (Interface Power Management) 2 : SPD (Interface Speed) 3 : DET (Device Detection (should be detected if COMINIT is received)) HBA_PORT__PxSERR: 0x040d0000 [80000130] 1 : DIAG.X (Exchanged (set on COMINIT), reflected in PxIS.PCS) 1 : DIAG.B (10B to 8B decode error) 1 : DIAG.W (COMMWAKE signal was detected) 1 : DIAG.N (PhyRdy changed. Reflected in PxIS.PRCS bit.) HBA_PORT__PxCI: 0x00000000 [80000138] >>> hex(mem.read_mem(0x80000ff0)) '0x3916f53' >>> _=mem.mem_dump (0x38110000, 0x100,4) 0x38110000:3fff0040 0010c837 00000000 0000003f 00000000 33393133 34303535 33353030 20202020 20202020 00000000 58320000 32303331 53613020 69736e44 53446b20 0x38110040:46313653 32384d31 20204720 20202020 20202020 20202020 20202020 80012020 2f004000 02004000 00070000 00103fff fc10003f 010100fb 0ee7c2b0 00070000 0x38110080:00780003 00780078 40200078 00000000 00000000 001f0000 0084870e 0040014c 002801f0 7d09346b 34694123 4123bc09 0001207f 00800006 0000fffe 00000000 0x381100c0:00000000 00000000 0ee7c2b0 00000000 00100000 00004000 b44a5001 2d633bf2 00000000 00000000 00000000 401c0000 0000401c 00000000 00000000 00000000 0x38110100:00000021 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110140:00000000 00000000 00000000 00000000 0001000b 00000000 00000000 00000000 20202020 20202020 20202020 20202020 20202020 20202020 20202020 20202020 0x38110180:20202020 20202020 20202020 20202020 20202020 20202020 20202020 00000000 40000000 00000000 00000000 00000000 00010000 00000000 00000000 0000103f 0x381101c0:00000000 00000000 00000000 00000000 00000000 00800001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4da50000 0x38110200:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110240:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110280:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x381102c0:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110300:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110340:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x38110380:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x381103c0:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x27900000:00ec8027 04030201 08070605 0c0b0a09 100f0e0d 14131211 18171615 1c1b1a19 201f1e1d 24232221 28272625 00000000 00000000 00000000 00000000 00000000 0x27900040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:00000000 00000000 00000000 00ec8027 04030201 08070605 0c0b0a09 100f0e0d 14131211 18171615 1c1b1a19 201f1e1d 24232221 28272625 00000000 00000000 0x80001040:00000000 00000000 00000000 00000000 00000014 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:40000000 40100000 40200000 403c8027 40430201 40570605 406b0a09 407f0e0d 40831211 40971615 40ab1a19 40bf1e1d 40c32221 40d72625 00e00000 00f00000 0x80001040:01000000 81100000 00000012 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:40000000 40100000 40200000 403c8027 40430201 40570605 406b0a09 407f0e0d 40831211 40971615 40d32221 00e72625 00f00000 01000000 81100000 0000000f 0x80001040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x27900000:00ec8027 11111111 22222222 33333333 44444444 55555555 66666666 77777777 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x27900040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000e 00000000 0x80001040:00000000 00000000 00000012 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001000:00000000 00000000 00000000 00ec8027 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80001040:00000000 00000000 00000012 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80000000:00240020 80000000 00000000 00000001 00010301 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80000040:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0x80000080:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Loading