From: Luke Kenneth Casson Leighton Date: Tue, 4 May 2021 19:21:04 +0000 (+0100) Subject: remove minerva debug unit (not needed) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=636f6dd26473e086ed3210752e77e72cc2b98e6c;p=soc.git remove minerva debug unit (not needed) --- diff --git a/src/soc/minerva/units/debug/__init__.py b/src/soc/minerva/units/debug/__init__.py deleted file mode 100644 index 08dee6da..00000000 --- a/src/soc/minerva/units/debug/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .top import * diff --git a/src/soc/minerva/units/debug/controller.py b/src/soc/minerva/units/debug/controller.py deleted file mode 100644 index 7304303e..00000000 --- a/src/soc/minerva/units/debug/controller.py +++ /dev/null @@ -1,201 +0,0 @@ -from nmigen import Elaboratable, Module, Signal, Array, Record -from nmigen.lib.coding import PriorityEncoder - -from ...csr import AutoCSR, CSR -from ...isa import dcsr_layout, flat_layout -from ...wishbone import wishbone_layout -from .dmi import DebugReg, Command, Error, Version, cmd_access_reg_layout - - -__all__ = ["DebugController"] - - -class HaltCause: - EBREAK = 1 - TRIGGER = 0 - HALTREQ = 3 - STEP = 4 - RESET_HALTREQ = 2 - - -cause_map = [2, 1, 5, 3, 4] - - -class DebugController(Elaboratable, AutoCSR): - def __init__(self, debugrf): - self.dcsr = CSR(0x7b0, dcsr_layout, name="dcsr") - self.dpc = CSR(0x7b1, flat_layout, name="dpc") - - self.dmstatus = debugrf.reg_port(DebugReg.DMSTATUS) - self.dmcontrol = debugrf.reg_port(DebugReg.DMCONTROL) - self.hartinfo = debugrf.reg_port(DebugReg.HARTINFO) - self.abstractcs = debugrf.reg_port(DebugReg.ABSTRACTCS) - self.command = debugrf.reg_port(DebugReg.COMMAND) - self.data0 = debugrf.reg_port(DebugReg.DATA0) - - self.trigger_haltreq = Signal() - - self.x_pc = Signal(32) - self.x_ebreak = Signal() - self.x_stall = Signal() - - self.m_branch_taken = Signal() - self.m_branch_target = Signal(32) - self.m_mret = Signal() - self.m_exception = Signal() - self.m_pc = Signal(32) - self.m_valid = Signal() - self.mepc_r_base = Signal(30) - self.mtvec_r_base = Signal(30) - - self.halt = Signal() - self.halted = Signal() - self.killall = Signal() - self.resumereq = Signal() - self.resumeack = Signal() - - self.gprf_addr = Signal(5) - self.gprf_re = Signal() - self.gprf_dat_r = Signal(32) - self.gprf_we = Signal() - self.gprf_dat_w = Signal(32) - - self.csrf_addr = Signal(12) - self.csrf_re = Signal() - self.csrf_dat_r = Signal(32) - self.csrf_we = Signal() - self.csrf_dat_w = Signal(32) - - def elaborate(self, platform): - m = Module() - - for csr in self.dcsr, self.dpc: - with m.If(csr.we): - m.d.sync += csr.r.eq(csr.w) - - with m.If(self.dmcontrol.update): - m.d.sync += [ - self.dmcontrol.w.dmactive.eq(self.dmcontrol.r.dmactive), - self.dmcontrol.w.ndmreset.eq(self.dmcontrol.r.ndmreset), - self.dmcontrol.w.hartselhi.eq(self.dmcontrol.r.hartselhi), - self.dmcontrol.w.hartsello.eq(self.dmcontrol.r.hartsello), - self.dmcontrol.w.hasel.eq(self.dmcontrol.r.hasel), - self.dmcontrol.w.hartreset.eq(self.dmcontrol.r.hartreset), - self.dmcontrol.w.resumereq.eq(self.dmcontrol.r.resumereq) - ] - - with m.If(self.abstractcs.update): - m.d.sync += self.abstractcs.w.cmderr.eq(self.abstractcs.r.cmderr) - - m.d.comb += [ - self.dmstatus.w.version.eq(Version.V013), - self.dmstatus.w.authenticated.eq(1), - self.resumereq.eq(self.dmcontrol.w.resumereq) - ] - - m_breakpoint = Signal() - with m.If(~self.x_stall): - m.d.comb += m_breakpoint.eq(self.x_ebreak & self.dcsr.r.ebreakm) - - halt_pe = m.submodules.halt_pe = PriorityEncoder(5) - m.d.comb += [ - halt_pe.i[HaltCause.EBREAK].eq(m_breakpoint & self.m_valid), - halt_pe.i[HaltCause.TRIGGER].eq(self.trigger_haltreq), - halt_pe.i[HaltCause.HALTREQ].eq(self.dmcontrol.r.haltreq), - halt_pe.i[HaltCause.STEP].eq(self.dcsr.r.step & self.m_valid), - ] - - with m.FSM(): - with m.State("RUN"): - m.d.comb += self.dmstatus.w.allrunning.eq(1) - with m.If(~halt_pe.n): - m.d.sync += [ - self.halt.eq(1), - self.dcsr.r.cause.eq(Array(cause_map)[halt_pe.o]), - self.dcsr.r.stepie.eq(1) - ] - with m.If(halt_pe.o == HaltCause.EBREAK): - m.d.sync += self.dpc.r.eq(self.m_pc) - with m.Elif(self.m_exception & self.m_valid): - m.d.sync += self.dpc.r.eq(self.mtvec_r_base << 30) - with m.Elif(self.m_mret & self.m_valid): - m.d.sync += self.dpc.r.eq(self.mepc_r_base << 30) - with m.Elif(self.m_branch_taken & self.m_valid): - m.d.sync += self.dpc.r.eq(self.m_branch_target) - with m.Else(): - m.d.sync += self.dpc.r.eq(self.x_pc) - m.next = "HALTING" - - with m.State("HALTING"): - with m.If(self.halted): - m.d.comb += self.killall.eq(1) - m.d.sync += self.dmstatus.w.allhalted.eq(1) - m.next = "WAIT" - - with m.State("WAIT"): - with m.If(self.dmcontrol.w.resumereq): - m.next = "RESUME" - with m.Elif(self.command.update): - m.d.sync += self.abstractcs.w.busy.eq(1) - m.next = "COMMAND:START" - - with m.State("RESUME"): - with m.If(self.resumeack): - m.d.sync += [ - self.dmcontrol.w.resumereq.eq(0), - self.dmstatus.w.allresumeack.eq(1), - self.halt.eq(0), - self.dmstatus.w.allhalted.eq(0) - ] - m.next = "RUN" - - with m.State("COMMAND:START"): - with m.Switch(self.command.r.cmdtype): - with m.Case(Command.ACCESS_REG): - control = Record(cmd_access_reg_layout) - m.d.comb += control.eq(self.command.r.control) - m.d.comb += self.gprf_addr.eq(control.regno) - m.next = "COMMAND:ACCESS-REG" - with m.Case(): - m.d.sync += self.abstractcs.w.cmderr.eq(Error.UNSUPPORTED) - m.next = "COMMAND:DONE" - - with m.State("COMMAND:ACCESS-REG"): - control = Record(cmd_access_reg_layout) - m.d.comb += control.eq(self.command.r.control) - with m.If(control.postexec | (control.aarsize != 2) | control.aarpostincrement): - # Unsupported parameters. - m.d.sync += self.abstractcs.w.cmderr.eq(Error.EXCEPTION) - with m.Elif((control.regno >= 0x0000) & (control.regno < 0x1000)): - with m.If(control.transfer): - m.d.comb += self.csrf_addr.eq(control.regno) - with m.If(control.write): - m.d.comb += [ - self.csrf_we.eq(1), - self.csrf_dat_w.eq(self.data0.r) - ] - with m.Else(): - m.d.comb += self.csrf_re.eq(1) - m.d.sync += self.data0.w.eq(self.csrf_dat_r) - m.d.sync += self.abstractcs.w.cmderr.eq(Error.NONE) - with m.Elif((control.regno >= 0x1000) & (control.regno < 0x1020)): - with m.If(control.transfer): - m.d.comb += self.gprf_addr.eq(control.regno) - with m.If(control.write): - m.d.comb += [ - self.gprf_we.eq(1), - self.gprf_dat_w.eq(self.data0.r) - ] - with m.Else(): - m.d.sync += self.data0.w.eq(self.gprf_dat_r) - m.d.sync += self.abstractcs.w.cmderr.eq(Error.NONE) - with m.Else(): - # Unknown register number. - m.d.sync += self.abstractcs.w.cmderr.eq(Error.EXCEPTION) - m.next = "COMMAND:DONE" - - with m.State("COMMAND:DONE"): - m.d.sync += self.abstractcs.w.busy.eq(0) - m.next = "WAIT" - - return m diff --git a/src/soc/minerva/units/debug/dmi.py b/src/soc/minerva/units/debug/dmi.py deleted file mode 100644 index 4298b2da..00000000 --- a/src/soc/minerva/units/debug/dmi.py +++ /dev/null @@ -1,147 +0,0 @@ -from enum import Enum - - -__all__ = [ - "Version", "Command", "Error", "RegMode", "DmiOp", "DebugReg", "dmstatus_layout", - "dmcontrol_layout", "abstractcs_layout", "cmd_access_reg_layout", "command_layout", - "sbcs_layout", "flat_layout" -] - - -class Version: - NONE = 0 - V011 = 1 - V013 = 2 - OTHER = 15 - - -class Command: - ACCESS_REG = 0 - QUICK_ACCESS = 1 - ACCESS_MEM = 2 - - -class Error: - NONE = 0 - BUSY = 1 - UNSUPPORTED = 2 - EXCEPTION = 3 - HALT_RESUME = 4 - - -RegMode = Enum("RegMode", ("R", "W", "W1", "RW", "RW1C", "WARL")) - - -class DmiOp: - NOP = 0 - READ = 1 - WRITE = 2 - - -# Debug registers - -class DebugReg: - DATA0 = 0x04 - DMCONTROL = 0x10 - DMSTATUS = 0x11 - HARTINFO = 0x12 - ABSTRACTCS = 0x16 - COMMAND = 0x17 - PROGBUF0 = 0x20 - SBCS = 0x38 - SBADDRESS0 = 0x39 - SBDATA0 = 0x3c - - -dmstatus_layout = [ - ("version", 4, RegMode.R, Version.V013), - ("confstrptrvalid", 1, RegMode.R, False), - ("hasresethaltreq", 1, RegMode.R, False), - ("authbusy", 1, RegMode.R, False), - ("authenticated", 1, RegMode.R, True), - ("anyhalted", 1, RegMode.R, False), - ("allhalted", 1, RegMode.R, False), - ("anyrunning", 1, RegMode.R, False), - ("allrunning", 1, RegMode.R, False), - ("anyunavail", 1, RegMode.R, False), - ("allunavail", 1, RegMode.R, False), - ("anynonexistent", 1, RegMode.R, False), - ("allnonexistent", 1, RegMode.R, False), - ("anyresumeack", 1, RegMode.R, False), - ("allresumeack", 1, RegMode.R, False), - ("anyhavereset", 1, RegMode.R, False), - ("allhavereset", 1, RegMode.R, False), - ("zero0", 2, RegMode.R, 0), - ("impebreak", 1, RegMode.R, False), - ("zero1", 9, RegMode.R, 0) -] - - -dmcontrol_layout = [ - ("dmactive", 1, RegMode.RW, False), - ("ndmreset", 1, RegMode.RW, False), - ("clrresethaltreq", 1, RegMode.W1, False), - ("setresethaltreq", 1, RegMode.W1, False), - ("zero0", 2, RegMode.R, 0), - ("hartselhi", 10, RegMode.RW, 0), - ("hartsello", 10, RegMode.RW, 0), - ("hasel", 1, RegMode.RW, False), - ("zero1", 1, RegMode.R, 0), - ("ackhavereset", 1, RegMode.W1, False), - ("hartreset", 1, RegMode.RW, False), - ("resumereq", 1, RegMode.W1, False), - ("haltreq", 1, RegMode.W, False) -] - - -abstractcs_layout = [ - ("datacount", 4, RegMode.R, 1), - ("zero0", 4, RegMode.R, 0), - ("cmderr", 3, RegMode.RW1C, 0), - ("zero1", 1, RegMode.R, 0), - ("busy", 1, RegMode.R, False), - ("zero2", 11, RegMode.R, 0), - ("progbufsize", 5, RegMode.R, 0), - ("zero3", 3, RegMode.R, 0) -] - - -cmd_access_reg_layout = [ - ("regno", 16), - ("write", 1), - ("transfer", 1), - ("postexec", 1), - ("aarpostincrement", 1), - ("aarsize", 3), - ("zero0", 1), -] - - -command_layout = [ - ("control", 24, RegMode.W, 0), - ("cmdtype", 8, RegMode.W, Command.ACCESS_REG) -] - - -sbcs_layout = [ - ("sbaccess8", 1, RegMode.R, True), - ("sbaccess16", 1, RegMode.R, True), - ("sbaccess32", 1, RegMode.R, True), - ("sbaccess64", 1, RegMode.R, False), - ("sbaccess128", 1, RegMode.R, False), - ("sbasize", 7, RegMode.R, 32), - ("sberror", 3, RegMode.RW1C, 0), - ("sbreadondata", 1, RegMode.RW, False), - ("sbautoincrement", 1, RegMode.RW, False), - ("sbaccess", 3, RegMode.RW, 2), - ("sbreadonaddr", 1, RegMode.RW, False), - ("sbbusy", 1, RegMode.R, False), - ("sbbusyerror", 1, RegMode.RW1C, False), - ("zero0", 6, RegMode.R, 0), - ("sbversion", 3, RegMode.R, 1) -] - - -flat_layout = [ - ("value", 32, RegMode.RW, 0) -] diff --git a/src/soc/minerva/units/debug/jtag.py b/src/soc/minerva/units/debug/jtag.py deleted file mode 100644 index 331dd512..00000000 --- a/src/soc/minerva/units/debug/jtag.py +++ /dev/null @@ -1,41 +0,0 @@ -from nmigen.hdl.rec import DIR_FANIN, DIR_FANOUT - - -__all__ = ["jtag_layout", "JTAGReg", "dtmcs_layout", "dmi_layout"] - - -jtag_layout = [ - ("tck", 1, DIR_FANIN), - ("tdi", 1, DIR_FANIN), - ("tdo", 1, DIR_FANOUT), - ("tms", 1, DIR_FANIN), - ("trst", 1, DIR_FANIN) # TODO -] - - -class JTAGReg: - BYPASS = 0x00 - IDCODE = 0x01 - DTMCS = 0x10 - DMI = 0x11 - - -# JTAG register layouts - -dtmcs_layout = [ - ("version", 4), - ("abits", 6), - ("dmistat", 2), - ("idle", 3), - ("zero0", 1), - ("dmireset", 1), - ("dmihardreset", 1), - ("zero1", 14) -] - - -dmi_layout = [ - ("op", 2), - ("data", 32), - ("addr", 6) -] diff --git a/src/soc/minerva/units/debug/regfile.py b/src/soc/minerva/units/debug/regfile.py deleted file mode 100644 index a7d3fd4f..00000000 --- a/src/soc/minerva/units/debug/regfile.py +++ /dev/null @@ -1,103 +0,0 @@ -from nmigen import Elaboratable, Module, Record, Const - -from .dmi import (DebugReg, DmiOp, RegMode, - abstractcs_layout, cmd_access_reg_layout, command_layout, - dmcontrol_layout, dmstatus_layout, flat_layout, sbcs_layout) - - -__all__ = ["DebugRegisterFile"] - - -class DmiOp: - NOP = 0 - READ = 1 - WRITE = 2 - - -class DmiResult: - OK = 0 - FAIL = 2 - BUSY = 3 - - -reg_map = { - DebugReg.DMSTATUS: dmstatus_layout, - DebugReg.DMCONTROL: dmcontrol_layout, - DebugReg.HARTINFO: flat_layout, - DebugReg.ABSTRACTCS: abstractcs_layout, - DebugReg.COMMAND: command_layout, - DebugReg.SBCS: sbcs_layout, - DebugReg.SBADDRESS0: flat_layout, - DebugReg.SBDATA0: flat_layout, - DebugReg.DATA0: flat_layout -} - - -class DebugRegisterFile(Elaboratable): - def __init__(self, dmi): - self.dmi = dmi - self.ports = dict() - - def reg_port(self, addr): - if addr not in reg_map: - raise ValueError("Unknown register {:x}.".format(addr)) - if addr in self.ports: - raise ValueError("Register {:x} has already been allocated.".format(addr)) - layout = [f[:2] for f in reg_map[addr]] - port = Record([("r", layout), ("w", layout), ("update", 1), ("capture", 1)]) - for name, shape, mode, reset in reg_map[addr]: - getattr(port.r, name).reset = reset - getattr(port.w, name).reset = reset - self.ports[addr] = port - return port - - def elaborate(self, platform): - m = Module() - - def do_read(addr, port): - rec = Record(port.w.layout) - m.d.sync += self.dmi.r.data.eq(rec) - for name, shape, mode, reset in reg_map[addr]: - dst = getattr(rec, name) - src = getattr(port.w, name) - if mode in {RegMode.R, RegMode.RW, RegMode.RW1C}: - m.d.comb += dst.eq(src) - else: - m.d.comb += dst.eq(Const(0)) - m.d.sync += port.capture.eq(1) - - def do_write(addr, port): - rec = Record(port.r.layout) - m.d.comb += rec.eq(self.dmi.w.data) - for name, shape, mode, reset in reg_map[addr]: - dst = getattr(port.r, name) - src = getattr(rec, name) - if mode in {RegMode.W, RegMode.RW}: - m.d.sync += dst.eq(src) - elif mode is RegMode.W1: - m.d.sync += dst.eq(getattr(port.w, name) | src) - elif mode is RegMode.RW1C: - m.d.sync += dst.eq(getattr(port.w, name) & ~src) - - m.d.sync += port.update.eq(1) - - with m.If(self.dmi.update): - with m.Switch(self.dmi.w.addr): - for addr, port in self.ports.items(): - with m.Case(addr): - with m.If(self.dmi.w.op == DmiOp.READ): - do_read(addr, port) - with m.Elif(self.dmi.w.op == DmiOp.WRITE): - do_write(addr, port) - m.d.sync += self.dmi.r.op.eq(DmiResult.OK) - with m.Case(): - # Invalid register. - m.d.sync += self.dmi.r.op.eq(DmiResult.FAIL) - - for port in self.ports.values(): - with m.If(port.update): - m.d.sync += port.update.eq(0) - with m.If(port.capture): - m.d.sync += port.capture.eq(0) - - return m diff --git a/src/soc/minerva/units/debug/top.py b/src/soc/minerva/units/debug/top.py deleted file mode 100644 index 2b82f0d5..00000000 --- a/src/soc/minerva/units/debug/top.py +++ /dev/null @@ -1,130 +0,0 @@ -from nmigen import Elaboratable, Module, Signal, Record - - -from ...wishbone import wishbone_layout -from .controller import DebugController -from .jtag import JTAGReg, dtmcs_layout, dmi_layout, jtag_layout -from .regfile import DebugRegisterFile -from .wbmaster import wishbone_layout, DebugWishboneMaster - -# FIXME: figure out where JTAGTap is -# from jtagtap import JTAGTap - - -class JTAGTap: - def __init__(self): - raise NotImplementedError( - "jtagtap package not found: figure out where JTAGTap is") - - -__all__ = ["DebugUnit"] - - -jtag_regs = { - JTAGReg.IDCODE: [("value", 32)], - JTAGReg.DTMCS: dtmcs_layout, - JTAGReg.DMI: dmi_layout -} - - -class DebugUnit(Elaboratable): - def __init__(self): - self.jtag = Record(jtag_layout) - self.dbus = Record(wishbone_layout) - - self.trigger_haltreq = Signal() - - self.x_ebreak = Signal() - self.x_pc = Signal(32) - self.x_stall = Signal() - - self.m_branch_taken = Signal() - self.m_branch_target = Signal(32) - self.m_mret = Signal() - self.m_exception = Signal() - self.m_pc = Signal(32) - self.m_valid = Signal() - self.mepc_r_base = Signal(30) - self.mtvec_r_base = Signal(30) - - self.dcsr_step = Signal() - self.dcsr_ebreakm = Signal() - self.dpc_value = Signal(32) - - self.halt = Signal() - self.halted = Signal() - self.killall = Signal() - self.resumereq = Signal() - self.resumeack = Signal() - - self.dbus_busy = Signal() - - self.csrf_addr = Signal(12) - self.csrf_re = Signal() - self.csrf_dat_r = Signal(32) - self.csrf_we = Signal() - self.csrf_dat_w = Signal(32) - - self.gprf_addr = Signal(5) - self.gprf_re = Signal() - self.gprf_dat_r = Signal(32) - self.gprf_we = Signal() - self.gprf_dat_w = Signal(32) - - def elaborate(self, platform): - m = Module() - - tap = m.submodules.tap = JTAGTap(jtag_regs) - regfile = m.submodules.regfile = DebugRegisterFile( - tap.regs[JTAGReg.DMI]) - controller = m.submodules.controller = DebugController(regfile) - wbmaster = m.submodules.wbmaster = DebugWishboneMaster(regfile) - - m.d.comb += [ - tap.port.connect(self.jtag), - # Usurpate a Spike core for now. - tap.regs[JTAGReg.IDCODE].r.eq(0x10e31913), - tap.regs[JTAGReg.DTMCS].r.eq(0x61) # (abits=6, version=1) TODO - ] - - m.d.comb += [ - controller.trigger_haltreq.eq(self.trigger_haltreq), - - controller.x_ebreak.eq(self.x_ebreak), - controller.x_pc.eq(self.x_pc), - controller.x_stall.eq(self.x_stall), - - controller.m_branch_taken.eq(self.m_branch_taken), - controller.m_branch_target.eq(self.m_branch_target), - controller.m_pc.eq(self.m_pc), - controller.m_valid.eq(self.m_valid), - - self.halt.eq(controller.halt), - controller.halted.eq(self.halted), - self.killall.eq(controller.killall), - self.resumereq.eq(controller.resumereq), - controller.resumeack.eq(self.resumeack), - - self.dcsr_step.eq(controller.dcsr.r.step), - self.dcsr_ebreakm.eq(controller.dcsr.r.ebreakm), - self.dpc_value.eq(controller.dpc.r.value), - - self.csrf_addr.eq(controller.csrf_addr), - self.csrf_re.eq(controller.csrf_re), - controller.csrf_dat_r.eq(self.csrf_dat_r), - self.csrf_we.eq(controller.csrf_we), - self.csrf_dat_w.eq(controller.csrf_dat_w), - - self.gprf_addr.eq(controller.gprf_addr), - self.gprf_re.eq(controller.gprf_re), - controller.gprf_dat_r.eq(self.gprf_dat_r), - self.gprf_we.eq(controller.gprf_we), - self.gprf_dat_w.eq(controller.gprf_dat_w), - ] - - m.d.comb += [ - wbmaster.bus.connect(self.dbus), - self.dbus_busy.eq(wbmaster.dbus_busy) - ] - - return m diff --git a/src/soc/minerva/units/debug/wbmaster.py b/src/soc/minerva/units/debug/wbmaster.py deleted file mode 100644 index db02af95..00000000 --- a/src/soc/minerva/units/debug/wbmaster.py +++ /dev/null @@ -1,125 +0,0 @@ -from functools import reduce -from operator import or_ - -from nmigen import Elaboratable, Module, Signal, Record - -from ...wishbone import wishbone_layout -from .dmi import DebugReg - - -__all__ = ["BusError", "AccessSize", "DebugWishboneMaster"] - - -class BusError: - NONE = 0 - TIMEOUT = 1 - BAD_ADDRESS = 2 - MISALIGNED = 3 - BAD_SIZE = 4 - OTHER = 7 - - -class AccessSize: - BYTE = 0 - HALF = 1 - WORD = 2 - - -class DebugWishboneMaster(Elaboratable): - def __init__(self, debugrf): - self.bus = Record(wishbone_layout) - - self.dbus_busy = Signal() - - self.sbcs = debugrf.reg_port(DebugReg.SBCS) - self.sbaddress0 = debugrf.reg_port(DebugReg.SBADDRESS0) - self.sbdata0 = debugrf.reg_port(DebugReg.SBDATA0) - - def elaborate(self, platform): - m = Module() - - addr = self.sbaddress0.w.value - size = self.sbcs.r.sbaccess - - width = Signal(6) - m.d.comb += width.eq((1< AccessSize.WORD): - m.d.sync += sberror.eq(BusError.BAD_SIZE) - with m.Elif((addr & (1<> addr[:2]*8) & (1<