int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id) { immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; law83xx_t *ecm = &immap->sysconf.ddrlaw[0]; u64 start_align, law_sz; int law_sz_enc; if (start == 0) start_align = 1ull << (LAW_SIZE_2G + 1); else start_align = 1ull << (ffs64(start) - 1); law_sz = min(start_align, sz); law_sz_enc = __ilog2_u64(law_sz) - 1; /* * Set up LAWBAR for all of DDR. */ ecm->bar = start & 0xfffff000; ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); debug("DDR:bar=0x%08x\n", ecm->bar); debug("DDR:ar=0x%08x\n", ecm->ar); /* recalculate size based on what was actually covered by the law */ law_sz = 1ull << __ilog2_u64(law_sz); /* do we still have anything to map */ sz = sz - law_sz; if (sz) { start += law_sz; start_align = 1ull << (ffs64(start) - 1); law_sz = min(start_align, sz); law_sz_enc = __ilog2_u64(law_sz) - 1; ecm = &immap->sysconf.ddrlaw[1]; ecm->bar = start & 0xfffff000; ecm->ar = (LAWAR_EN | (id << 20) | (LAWAR_SIZE & law_sz_enc)); debug("DDR:bar=0x%08x\n", ecm->bar); debug("DDR:ar=0x%08x\n", ecm->ar); } else { return 0; } /* do we still have anything to map */ sz = sz - law_sz; if (sz) return 1; return 0; }
size_t dirtio_allocv(struct diodevice *dio, struct iovec *iovec, int num, size_t len) { int i, n, b; struct iovec *iov = iovec; n = 0; for (i = 0; i < DIRTIO_BUFBMAPSZ(dio); i++) { printf("dio->bmap[i] = %llx\n", dio->bmap[i]); while (dio->bmap[i] != (uint64_t)-1) { b = ffs64(~dio->bmap[i]) - 1; assert(b != -1); dio->bmap[i] |= ((uint64_t)1 << b); iov->iov_base = GETBUF(dio, i * 64 + b); iov->iov_len = len < dio->bufsz ? len : dio->bufsz; len -= iov->iov_len; iov++; n++; if (len == 0 || n == num) goto out; } } out: return len; }
TEST(BitopsTest, FfsNonzero) { int64_t out; int64_t one = 1; bool res; for (int i = 0; i < 63; i++) { res = ffs64(one << i, out); EXPECT_TRUE(res); EXPECT_EQ(i, out); } }
/* use up to 2 LAWs for DDR, used the last available LAWs */ int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id) { u64 start_align, law_sz; int law_sz_enc; if (start == 0) start_align = 1ull << (LAW_SIZE_32G + 1); else start_align = 1ull << (ffs64(start) - 1); law_sz = min(start_align, sz); law_sz_enc = __ilog2_u64(law_sz) - 1; if (set_last_law(start, law_sz_enc, id) < 0) return -1; /* recalculate size based on what was actually covered by the law */ law_sz = 1ull << __ilog2_u64(law_sz); /* do we still have anything to map */ sz = sz - law_sz; if (sz) { start += law_sz; start_align = 1ull << (ffs64(start) - 1); law_sz = min(start_align, sz); law_sz_enc = __ilog2_u64(law_sz) - 1; if (set_last_law(start, law_sz_enc, id) < 0) return -1; } else { return 0; } /* do we still have anything to map */ sz = sz - law_sz; if (sz) return 1; return 0; }
int comb_elem(comb_t *comb) { int idx; if (comb == NULL) return -1; if (*comb == 0) return -1; idx = ffs64(*comb); *comb &= *comb - 1; return idx; }
TEST(BitopsTest, FfsZero) { int64_t zero = 0; int64_t out; EXPECT_FALSE(ffs64(zero, out)); }