* vmem_fit: check if a bt can satisfy the given restrictions. * * it's a caller's responsibility to ensure the region is big enough * before calling us. */
| 943 | * before calling us. |
| 944 | */ |
| 945 | static int |
| 946 | vmem_fit(const bt_t *bt, vmem_size_t size, vmem_size_t align, |
| 947 | vmem_size_t phase, vmem_size_t nocross, vmem_addr_t minaddr, |
| 948 | vmem_addr_t maxaddr, vmem_addr_t *addrp) |
| 949 | { |
| 950 | vmem_addr_t start; |
| 951 | vmem_addr_t end; |
| 952 | |
| 953 | MPASS(size > 0); |
| 954 | MPASS(bt->bt_size >= size); /* caller's responsibility */ |
| 955 | |
| 956 | /* |
| 957 | * XXX assumption: vmem_addr_t and vmem_size_t are |
| 958 | * unsigned integer of the same size. |
| 959 | */ |
| 960 | |
| 961 | start = bt->bt_start; |
| 962 | if (start < minaddr) { |
| 963 | start = minaddr; |
| 964 | } |
| 965 | end = BT_END(bt); |
| 966 | if (end > maxaddr) |
| 967 | end = maxaddr; |
| 968 | if (start > end) |
| 969 | return (ENOMEM); |
| 970 | |
| 971 | start = VMEM_ALIGNUP(start - phase, align) + phase; |
| 972 | if (start < bt->bt_start) |
| 973 | start += align; |
| 974 | if (VMEM_CROSS_P(start, start + size - 1, nocross)) { |
| 975 | MPASS(align < nocross); |
| 976 | start = VMEM_ALIGNUP(start - phase, nocross) + phase; |
| 977 | } |
| 978 | if (start <= end && end - start >= size - 1) { |
| 979 | MPASS((start & (align - 1)) == phase); |
| 980 | MPASS(!VMEM_CROSS_P(start, start + size - 1, nocross)); |
| 981 | MPASS(minaddr <= start); |
| 982 | MPASS(maxaddr == 0 || start + size - 1 <= maxaddr); |
| 983 | MPASS(bt->bt_start <= start); |
| 984 | MPASS(BT_END(bt) - start >= size - 1); |
| 985 | *addrp = start; |
| 986 | |
| 987 | return (0); |
| 988 | } |
| 989 | return (ENOMEM); |
| 990 | } |
| 991 | |
| 992 | /* |
| 993 | * vmem_clip: Trim the boundary tag edges to the requested start and size. |
no outgoing calls
no test coverage detected