40#include <sys/malloc.h>
143pcib_child_name(device_t
child)
147 if (device_get_nameunit(
child) != NULL)
148 return (device_get_nameunit(
child));
149 snprintf(buf,
sizeof(buf),
"pci%d:%d:%d:%d", pci_get_domain(
child),
166pcib_host_res_init(device_t
pcib,
struct pcib_host_resources *hr)
170 resource_list_init(&hr->hr_rl);
175pcib_host_res_free(device_t
pcib,
struct pcib_host_resources *hr)
178 resource_list_free(&hr->hr_rl);
183pcib_host_res_decodes(
struct pcib_host_resources *hr,
int type, rman_res_t
start,
184 rman_res_t end, u_int flags)
186 struct resource_list_entry *rle;
190 device_printf(hr->hr_pcib,
"decoding %d %srange %#jx-%#jx\n",
191 type, flags & RF_PREFETCHABLE ?
"prefetchable ":
"",
start,
193 rid = resource_list_add_next(&hr->hr_rl,
type,
start, end,
195 if (flags & RF_PREFETCHABLE) {
196 KASSERT(
type == SYS_RES_MEMORY,
197 (
"only memory is prefetchable"));
198 rle = resource_list_find(&hr->hr_rl,
type,
rid);
199 rle->flags = RLE_PREFETCH;
205pcib_host_res_alloc(
struct pcib_host_resources *hr, device_t
dev,
int type,
206 int *
rid, rman_res_t
start, rman_res_t end, rman_res_t
count, u_int flags)
208 struct resource_list_entry *rle;
210 rman_res_t new_start, new_end;
212 if (flags & RF_PREFETCHABLE)
213 KASSERT(
type == SYS_RES_MEMORY,
214 (
"only memory is prefetchable"));
216 rle = resource_list_find(&hr->hr_rl,
type, 0);
222 return (bus_generic_alloc_resource(hr->hr_pcib,
dev,
type,
rid,
228 for (; rle != NULL; rle = STAILQ_NEXT(rle, link)) {
229 if (rle->type !=
type)
231 if (((flags & RF_PREFETCHABLE) != 0) !=
232 ((rle->flags & RLE_PREFETCH) != 0))
234 new_start = ummax(
start, rle->start);
235 new_end = ummin(end, rle->end);
236 if (new_start > new_end ||
237 new_start +
count - 1 > new_end ||
238 new_start +
count < new_start)
240 r = bus_generic_alloc_resource(hr->hr_pcib,
dev,
type,
rid,
241 new_start, new_end,
count, flags);
244 device_printf(hr->hr_pcib,
245 "allocated type %d (%#jx-%#jx) for rid %x of %s\n",
246 type, rman_get_start(r), rman_get_end(r),
247 *
rid, pcib_child_name(
dev));
256 if (flags & RF_PREFETCHABLE) {
257 flags &= ~RF_PREFETCHABLE;
258 rle = resource_list_find(&hr->hr_rl,
type, 0);
265pcib_host_res_adjust(
struct pcib_host_resources *hr, device_t
dev,
int type,
266 struct resource *r, rman_res_t
start, rman_res_t end)
268 struct resource_list_entry *rle;
270 rle = resource_list_find(&hr->hr_rl,
type, 0);
276 return (bus_generic_adjust_resource(hr->hr_pcib,
dev,
type, r,
281 for (; rle != NULL; rle = STAILQ_NEXT(rle, link)) {
282 if (rle->start <=
start && rle->end >= end)
283 return (bus_generic_adjust_resource(hr->hr_pcib,
dev,
292 struct rman pd_bus_rman;
293 TAILQ_ENTRY(pci_domain) pd_link;
296static TAILQ_HEAD(, pci_domain) domains = TAILQ_HEAD_INITIALIZER(domains);
304static struct pci_domain *
305pci_find_domain(
int domain)
307 struct pci_domain *d;
311 TAILQ_FOREACH(d, &domains, pd_link) {
312 if (d->pd_domain == domain)
316 snprintf(buf,
sizeof(buf),
"PCI domain %d bus numbers", domain);
317 d = malloc(
sizeof(*d) + strlen(buf) + 1, M_DEVBUF, M_WAITOK | M_ZERO);
318 d->pd_domain = domain;
319 d->pd_bus_rman.rm_start = 0;
321 d->pd_bus_rman.rm_type = RMAN_ARRAY;
322 strcpy((
char *)(d + 1), buf);
323 d->pd_bus_rman.rm_descr = (
char *)(d + 1);
324 error = rman_init(&d->pd_bus_rman);
326 error = rman_manage_region(&d->pd_bus_rman, 0,
PCI_BUSMAX);
328 panic(
"Failed to initialize PCI domain %d rman", domain);
329 TAILQ_INSERT_TAIL(&domains, d, pd_link);
334pci_domain_alloc_bus(
int domain, device_t
dev,
int *
rid, rman_res_t
start,
335 rman_res_t end, rman_res_t
count, u_int flags)
337 struct pci_domain *d;
338 struct resource *res;
342 d = pci_find_domain(domain);
343 res = rman_reserve_resource(&d->pd_bus_rman,
start, end,
count, flags,
348 rman_set_rid(res, *
rid);
353pci_domain_adjust_bus(
int domain, device_t
dev,
struct resource *r,
354 rman_res_t
start, rman_res_t end)
357 struct pci_domain *d;
363 d = pci_find_domain(domain);
364 KASSERT(rman_is_region_manager(r, &d->pd_bus_rman), (
"bad resource"));
366 return (rman_adjust_resource(r,
start, end));
370pci_domain_release_bus(
int domain, device_t
dev,
int rid,
struct resource *r)
373 struct pci_domain *d;
379 d = pci_find_domain(domain);
380 KASSERT(rman_is_region_manager(r, &d->pd_bus_rman), (
"bad resource"));
382 return (rman_release_resource(r));
METHOD u_int32_t read_config
int host_pcib_get_busno(pci_read_config_fn read_config, int bus, int slot, int func, uint8_t *busnum)
uint32_t pci_read_config_fn(int b, int s, int f, int reg, int width)