def build_and_write_code(heap, code): page = heap.memalign(0x4000, 0x4000) compiled = asm.ARMAsm(code, page).data iface.writemem(page, compiled) p.dc_cvau(page, len(compiled)) p.ic_ivau(page, len(compiled)) return page
def find_regs(u, regs=None, block=1024, call=None, values=True): if regs is None: regs = impdef_regs p = u.proxy iface = u.iface data_len = 8 * block with GuardedHeap(u.heap) as heap: data_buffer = heap.malloc(data_len) template = asm.ARMAsm(""" mov x2, x0 mrs x2, s3_0_c0_c0_0 str x2, [x1], #8 """, 0x1000) mov, mrs, st = struct.unpack("3I", template.data) data = [] BAD = 0xacce5515abad1dea OOPS = 0xdeadc0dedeadc0de rblock = [] iregs = iter(regs) while True: insns = [] bregs = [] for i in iregs: op0, op1, CRn, CRm, op2 = enc = sysreg.sysreg_parse(i) bregs.append(enc) assert op0 == 3 insns.extend((mov, mrs | (op1 << 16) | (CRn << 12) | (CRm << 8) | (op2 << 5), st)) if len(bregs) >= block: break if not bregs: break p.memset64(data_buffer, OOPS, data_len) u.exec(insns, BAD, data_buffer, call=call, silent=True, ignore_exceptions=True) data = iface.readmem(data_buffer, 8 * len(bregs)) for reg, val in zip(bregs, struct.unpack(f"<{len(bregs)}Q", data)): if val == OOPS: raise Exception(f"Failed to execute reg-finder code at {reg}") if val != BAD: if values: yield reg, val else: yield reg
def test_smp_ipi(): code = u.malloc(0x1000) c = asm.ARMAsm( """ #define sys_reg(op0, op1, CRn, CRm, op2) s##op0##_##op1##_c##CRn##_c##CRm##_##op2 #define SYS_CYC_OVRD sys_reg(3, 5, 15, 5, 0) msr DAIFClr, 7 ldr x1, =0x000000 msr SYS_CYC_OVRD, x1 mrs x0, SYS_CYC_OVRD mov x1, #0x1000000 1: subs x1, x1, #1 mrs x0, HCR_EL2 bne 1b ret """, code) iface.writemem(code, c.data) p.dc_cvau(code, len(c.data)) p.ic_ivau(code, len(c.data)) print("Enable IRQs on secondaries") for i in range(1, 8): ret = p.smp_call_sync(i, code) print("0x%x" % ret) #e0477971 #p.write32(AIC + 0x10, 0xe0777971) #p.write32(AIC + 0x28, 0xffffffff) cpoll() print("Clear IPI") p.write32(AIC_IPI_CLR, 0xffffffff) p.write32(AIC_IPI_MASK_CLR, 0xffffffff) for i in range(8): p.write32(AIC_IPI_CLR + 0x3000 + i * 0x80, 0xffffffff) p.write32(AIC_IPI_MASK_CLR + 0x3000 + i * 0x80, 0xffffffff) cpoll() print("Set IPI") #p.write32(AIC_IPI_SET, 0x00000004) #p.write32(AIC_IPI_SET, 0x00000000) cpoll() print("Clear IPI") p.write32(AIC_IPI_CLR, 0xffffffff) p.write32(AIC_IPI_MASK_CLR, 0xffffffff) for i in range(8): p.write32(AIC_IPI_CLR + 0x3000 + i * 0x80, 1) p.write32(AIC_IPI_MASK_CLR + 0x3000 + i * 0x80, 1)
else: tba.video.display = 1 print(f"Setting boot arguments to {boot_args!r}") tba.cmdline = boot_args iface.writemem(image_addr + bootargs_off, BootArgs.build(tba)) print(f"Copying stub...") stub = asm.ARMAsm(f""" 1: ldp x4, x5, [x1], #8 stp x4, x5, [x2] dc cvau, x2 ic ivau, x2 add x2, x2, #8 sub x3, x3, #8 cbnz x3, 1b ldr x1, ={entry} br x1 """, image_addr + image_size) iface.writemem(stub.addr, stub.data) p.dc_cvau(stub.addr, stub.len) p.ic_ivau(stub.addr, stub.len) print(f"Entry point: 0x{entry:x}") if args.call: print(f"Shutting down MMU...")
from setup import * import asm p.iodev_set_usage(IODEV.FB, 0) code_len = 12 * 16 * 8 + 4 data_len = 8 * 16 * 8 code_buffer = p.malloc(code_len) data_buffer = p.malloc(data_len) template = asm.ARMAsm( """ mov x2, x0 mrs x2, s3_0_c0_c0_0 str x2, [x1], #8 ret """, code_buffer) mov, mrs, st, ret = struct.unpack("4I", template.data) data = [] BAD = 0xacce5515abad1dea def find_regs(call=None): if not call: call = p.call regs = set() for op1 in range(1 << 3):
AFPCR = (3, 6, 15, 2, 5) AFPCR_DAZ = 1 << 0 AFPCR_FTZ = 1 << 1 code_buffer = p.malloc(0x1000) data_buffer = p.malloc(0x1000) code = asm.ARMAsm( """ ldr s0, [x0, #0] ldr s1, [x0, #4] fmul s0, s1, s0 str s0, [x0, #8] ldr s0, [x0, #12] ldr s1, [x0, #16] fmul s0, s1, s0 str s0, [x0, #20] # to test EL0 access # mrs x0, s3_6_c15_c2_5 ret """, code_buffer) iface.writemem(code_buffer, code.data) p.dc_cvau(code_buffer, code.len) p.ic_ivau(code_buffer, code.len) def test_denormals():
def test_uart_irq(): cpoll() #p.memset32(AIC_MASK_CLR, 0xffffffff, 0x80) print("cleanup") p.write32(UCON, 5) p.write32(UFCON, 0x11) p.write32(UTRSTAT, 0xfff) cpoll() for irq in range(600, 610): #print("S: ", get_irq_state(irq)) p.write32(AIC_SW_GEN_CLR + 4 * (irq // 32), 1 << (irq % 32)) #print("S: ", get_irq_state(irq)) #print("a") #print("S: ", get_irq_state(irq)) p.write32(AIC_MASK_CLR + 4 * (irq // 32), 1 << (irq % 32)) #print("S: ", get_irq_state(irq)) #print("b") irq = 605 cpoll() print("a") print("S: ", get_irq_state(irq)) print("ucon: %x" % p.read32(UCON)) TX_IRQ_EN = 0x1000 RX_IRQ_ENABLE = 0x20000 RX_IRQ_UNMASK = 0x10000 RX_IRQ_ENA = 0x20000 RX_IRQ_MASK = 0x4000 # defer? code = u.malloc(0x1000) c = asm.ARMAsm( """ ldr x1, =0x235200000 ldr x3, =0xc000000 1: subs x3, x3, #1 bne 1b mov x2, 'A' #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] #str w2, [x1, #0x20] mov x3, #0x3ff str w3, [x1, #0x10] #str w2, [x1, #0x20] str w0, [x1, #4] ldr w0, [x1, #0x10] ldr x3, =0xc00000 1: subs x3, x3, #1 bne 1b #mov x3, #0x3ff #str w3, [x1, #0x10] #ldr w2, [x1, #4] #mov x2, #0x205 #str w2, [x1, #4] #str w0, [x1, #4] ##ldr w0, [x1, #0x10] #ldr x3, =0xc00000 #1: #subs x3, x3, #1 #bne 1b ldr w0, [x1, #0x10] #mov w0, w2 ret """, code) iface.writemem(code, c.data) p.dc_cvau(code, len(c.data)) p.ic_ivau(code, len(c.data)) #RX_IRQ_ """ UCON UTRSTAT 00200 TX FIFO thresh IRQ delivery enable 00080 0200 TX FIFO threshold IRQ unmask 20000 0100 RX IRQ unmask 10000 RX IRQ delivery enable """ # edge triggered TX_FIFO_THRESH_CROSSED_IRQ_UNMASK = 0x2000 TX_IRQ_UNMASK = 0x200 TX_EVENT_ENABLE = 0x80 RX_EVENT_ENABLE = 0x20000 RX_IRQ_UNMASK = 0x10000 #flags = 0x7ffc0 crash = 0x180000 no_irqs = 0x21c5c0 instant_irqs = 0x3a00 #flags = no_irqs | 0x0000 #flags = 0x2e5c0 #flags = 0x2000 #flags = 0x30000 #flags = 0x80 flags = 0x7ff80 val = flags | 0x005 #print("ucon<-%x" % val) #p.write32(UCON, val) p.write32(UTRSTAT, 0xfff) print("utrstat=%x" % p.read32(UTRSTAT)) ret = p.call(code, val) print("utrstat::%x" % ret) print("utrstat=%x" % p.read32(UTRSTAT)) time.sleep(0.5) iface.dev.write(b'1') #print(iface.dev.read(1)) time.sleep(0.1) print("ucon: %x" % p.read32(UCON)) print("delay") try: p.udelay(500000) except: pass iface.dev.write(bytes(64)) p.nop() print("ucon: %x" % p.read32(UCON)) print("S: ", get_irq_state(irq))