Beispiel #1
0
 def gen_mmio_size(regs):
     if regs is None:
         return CINT(0x100, 16, 3)  # legacy default
     else:
         reg_range = get_reg_range(regs)
         digits = int(log(reg_range, 16)) + 1
         return CINT(reg_range, 16, digits)
Beispiel #2
0
    def __init__(
        self,
        size,
        # None or "gap" named registers are not backed by a state field
        name=None,
        access="rw",
        reset=0,
        full_name=None,
        # write mask (None corresponds 0b11...11. I.e. all bits are writable).
        wmask=None,
        # Write after read (WAR) bits. 1 marks the bit as WAR. None
        # corresponds to 0b00...00, all bits can be written without reading.
        warbits=None):
        super(Register, self).__init__(size, name)
        self.access = access
        self.reset = None if reset is None else CINT(reset, 16, size * 2)
        self.full_name = full_name

        if wmask is None:
            wmask = (1 << (size * 8)) - 1
        self.wmask = CINT(wmask, 2, size * 8)

        if warbits is None:
            warbits = 0
        self.warbits = CINT(warbits, 2, size * 8)
Beispiel #3
0
 def gen_mmio_size(regs):
     if regs is None:
         return CINT(0x100, 16, 3) # legacy default
     elif isinstance(regs, MemoryLeafNode):
         return regs.size
     else:
         reg_range = get_reg_range(regs)
         digits = int(log(reg_range, 16)) + 1
         return CINT(reg_range, 16, digits)
Beispiel #4
0
    def test_0b11100111(self):
        # If difference of digits amount in two CINT does not affects
        # string form, then it is negligible.

        # Right CINT requires at least 0 digits, It does not result in leading
        # zeros. Left CINT requires 8 digits, according to original string
        # form. It has no leading zeros, apparently. So, CINTs are considered
        # equal.
        self.assertEqual(CINT("0b11100111"), CINT(231, 2, 0))
        # Right CINT has 1 leading zero, CINTs are not equal.
        self.assertNotEqual(CINT("0b11100111"), CINT(231, 2, 9))
Beispiel #5
0
    def __init__(self, name, size, var_base="mem", **kw):
        Node.__init__(self, var_base=var_base, **kw)

        self.name = CSTR(name)
        self.size = None if size is None else CINT(size)

        self.parent = None
        self.offset = CINT(0, base=16)
        self.may_overlap = True
        self.priority = CINT(1)

        self.children = []

        self.alias_to = None
        self.alias_offset = CINT(0, base=16)
Beispiel #6
0
    def __repr__(self, *args, **kwargs):
        # TODO: adapt and utilize PyGenerator.gen_args for this use case

        ret = type(self).__name__
        size = self.size

        ret += "(" + repr(size)

        name = self.name
        if name is not None:
            ret += ", name = " + repr(name)

        access = self.access
        if access != "rw":
            ret += ", access = " + repr(access)

        reset = self.reset
        if reset != CINT(0, 16, size):
            ret += ", reset = " + repr(reset)

        fn = self.full_name
        if fn is not None:
            ret += ", full_name = " + repr(fn)

        wm = self.wmask
        if (wm.v != (1 << (size * 8)) - 1 or wm.b != 2 or wm.d != size * 8):
            ret += ", wmask = " + repr(wm)

        warb = self.warbits
        if (warb.v != 0 or warb.b != 2 or warb.d != size * 8):
            ret += ", warbits = " + repr(warb)

        ret += ")"
        return ret
Beispiel #7
0
 def test_0x18(self):
     self.assertEqual(CINT("0x18"), CINT(24, 16, 2))
Beispiel #8
0
 def test(self):
     self.assertEqual(CINT("0"), 0)
Beispiel #9
0
 def test(self):
     self.assertRaises(ValueError, lambda: CINT(""))
Beispiel #10
0
def gen_reg_cases(regs, access, offset_name, val, ret, s):
    reg_range = get_reg_range(regs)
    cases = []
    digits = int(log(reg_range, 16)) + 1

    offset = 0

    for reg in regs:
        size = reg.size

        name = reg.name
        if name is None or name == "gap":
            offset += size
            continue

        if size == 1:
            case_cond = CINT(offset, base = 16, digits = digits)
        else:
            case_cond = (
                CINT(offset, base = 16, digits = digits),
                CINT(offset + size - 1, base = 16, digits = digits)
            )
        offset += size

        case = SwitchCase(case_cond)

        comment = name
        if reg.full_name: # neither `None` nor empty string
            comment += ", " + reg.full_name

        case(Comment(comment))

        if access in reg.access:
            qtn = QemuTypeName(name)
            s_deref_war = lambda : OpSDeref(
                s,
                qtn.for_id_name + "_war"
            )
            s_deref = OpSDeref(
                s,
                qtn.for_id_name
            )

            if access == "r":
                case(
                    OpAssign(
                        ret,
                        s_deref
                    )
                )
                warb = reg.warbits
                if warb.v: # neither None nor zero
                    # There is at least one write-after-read bit in the reg.
                    wm = reg.wmask
                    if wm.v == (1 << (size * 8)) - 1:
                        # no read only bits: set WAR mask to 0xF...F
                        case(
                            OpAssign(
                                s_deref_war(),
                                OpNot(0)
                            )
                        )
                    else:
                        # writable bits, read only bits: init WAR mask with
                        # write mask
                        case(
                            OpAssign(
                                s_deref_war(),
                                wm
                            )
                        )
            elif access == "w":
                wm = reg.wmask
                warb = reg.warbits

                if warb.v and wm.v:
                    # WAR bits, writable, read only bits: use WAR mask as
                    # dynamic write mask
                    case(
                        OpAssign(
                            s_deref,
                            OpOr(
                                OpAnd(
                                    val,
                                    s_deref_war(),
                                    parenthesis = True
                                ),
                                OpAnd(
                                    s_deref,
                                    OpNot(
                                        s_deref_war()
                                    ),
                                    parenthesis = True
                                )
                            )
                        )
                    )
                elif wm.v == (1 << (size * 8)) - 1:
                    # no WAR bits, no read only bits
                    # write mask does not affect the value being assigned
                    case(
                        OpAssign(
                            s_deref,
                            val
                        )
                    )
                elif wm.v:
                    # no WAR bits, writable bits, read only bits: use static
                    # write mask
                    case(
                        OpAssign(
                            s_deref,
                            OpOr(
                                OpAnd(
                                    val,
                                    wm,
                                    parenthesis = True
                                ),
                                OpAnd(
                                    s_deref,
                                    OpNot(
                                        wm
                                    ),
                                    parenthesis = True
                                )
                            )
                        )
                    )
        else:
            case(
                Call(
                    "fprintf",
                    MCall("stderr"),
                    StrConcat(
                        CSTR(
"%%s: %s 0x%%0%d" % ("Reading from" if access == "r" else "Writing to", digits)
                        ),
                        MCall("HWADDR_PRIx"),
                        CSTR("\\n"),
                        delim = "@s"
                    ),
                    MCall("__func__"),
                    offset_name
                )
            )

        cases.append(case)

    return cases
Beispiel #11
0
    def __init__(self, name, size, alias_to, offset=CINT(0), **kw):
        MemoryLeafNode.__init__(self, name, size, **kw)

        self.alias_to = alias_to
        self.alias_offset = CINT(offset)
Beispiel #12
0
def gen_reg_cases(regs, access, offset_name, val, ret, s):
    reg_range = get_reg_range(regs)
    cases = []
    digits = int(log(reg_range, 16)) + 1

    offset = 0

    for reg in regs:
        size = reg.size
        if size == 1:
            case_cond = CINT(offset, base = 16, digits = digits)
        else:
            case_cond = (
                CINT(offset, base = 16, digits = digits),
                CINT(offset + size - 1, base = 16, digits = digits)
            )
        offset += size

        case = SwitchCase(case_cond)
        name = reg.name
        if name is not None:
            case.add_child(Comment(reg.name))

        if access in reg.access:
            qtn = QemuTypeName(name)
            s_deref_war = OpSDeref(
                s,
                qtn.for_id_name + "_war"
            )
            s_deref = OpSDeref(
                s,
                qtn.for_id_name
            )

            if access == "r":
                case.add_child(
                    OpAssign(
                        ret,
                        s_deref
                    )
                )
                warb = reg.warbits
                if warb.v: # neither None nor zero
                    # There is at least one write-after-read bit in the reg.
                    wm = reg.wmask
                    if wm.v == (1 << (size * 8)) - 1:
                        # no read only bits: set WAR mask to 0xF...F
                        case.add_child(
                            OpAssign(
                                s_deref_war,
                                OpNot(0)
                            )
                        )
                    else:
                        # writable bits, read only bits: init WAR mask with
                        # write mask
                        case.add_child(
                            OpAssign(
                                s_deref_war,
                                wm
                            )
                        )