Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/pci/pci_pci.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* This is used to reject I/O port allocations that conflict with an | * This is used to reject I/O port allocations that conflict with an | ||||
* ISA alias range. | * ISA alias range. | ||||
*/ | */ | ||||
static int | static int | ||||
pcib_is_isa_range(struct pcib_softc *sc, u_long start, u_long end, u_long count) | pcib_is_isa_range(struct pcib_softc *sc, rman_res_t start, rman_res_t end, | ||||
rman_res_t count) | |||||
{ | { | ||||
u_long next_alias; | rman_res_t next_alias; | ||||
if (!(sc->bridgectl & PCIB_BCR_ISA_ENABLE)) | if (!(sc->bridgectl & PCIB_BCR_ISA_ENABLE)) | ||||
return (0); | return (0); | ||||
/* Only check fixed ranges for overlap. */ | /* Only check fixed ranges for overlap. */ | ||||
if (start + count - 1 != end) | if (start + count - 1 != end) | ||||
return (0); | return (0); | ||||
Show All 15 Lines | |||||
next_alias = (start & ~0x3fful) | 0x100; | next_alias = (start & ~0x3fful) | 0x100; | ||||
if (next_alias <= end) | if (next_alias <= end) | ||||
goto alias; | goto alias; | ||||
return (0); | return (0); | ||||
alias: | alias: | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->dev, | device_printf(sc->dev, | ||||
"I/O range %#lx-%#lx overlaps with an ISA alias\n", start, | "I/O range %#jx-%#jx overlaps with an ISA alias\n", start, | ||||
end); | end); | ||||
return (1); | return (1); | ||||
} | } | ||||
static void | static void | ||||
pcib_add_window_resources(struct pcib_window *w, struct resource **res, | pcib_add_window_resources(struct pcib_window *w, struct resource **res, | ||||
int count) | int count) | ||||
{ | { | ||||
Show All 12 Lines | |||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
error = rman_manage_region(&w->rman, rman_get_start(res[i]), | error = rman_manage_region(&w->rman, rman_get_start(res[i]), | ||||
rman_get_end(res[i])); | rman_get_end(res[i])); | ||||
if (error) | if (error) | ||||
panic("Failed to add resource to rman"); | panic("Failed to add resource to rman"); | ||||
} | } | ||||
} | } | ||||
typedef void (nonisa_callback)(u_long start, u_long end, void *arg); | typedef void (nonisa_callback)(rman_res_t start, rman_res_t end, void *arg); | ||||
static void | static void | ||||
pcib_walk_nonisa_ranges(u_long start, u_long end, nonisa_callback *cb, | pcib_walk_nonisa_ranges(rman_res_t start, rman_res_t end, nonisa_callback *cb, | ||||
void *arg) | void *arg) | ||||
{ | { | ||||
u_long next_end; | rman_res_t next_end; | ||||
/* | /* | ||||
* If start is within an ISA alias range, move up to the start | * If start is within an ISA alias range, move up to the start | ||||
* of the next non-alias range. As a special case, addresses | * of the next non-alias range. As a special case, addresses | ||||
* in the range 0x000 - 0x0ff should also be skipped since | * in the range 0x000 - 0x0ff should also be skipped since | ||||
* those are used for various system I/O devices in ISA | * those are used for various system I/O devices in ISA | ||||
* systems. | * systems. | ||||
*/ | */ | ||||
Show All 11 Lines | |||||
start += 0x400; | start += 0x400; | ||||
} | } | ||||
if (start <= end) | if (start <= end) | ||||
cb(start, end, arg); | cb(start, end, arg); | ||||
} | } | ||||
static void | static void | ||||
count_ranges(u_long start, u_long end, void *arg) | count_ranges(rman_res_t start, rman_res_t end, void *arg) | ||||
{ | { | ||||
int *countp; | int *countp; | ||||
countp = arg; | countp = arg; | ||||
(*countp)++; | (*countp)++; | ||||
} | } | ||||
struct alloc_state { | struct alloc_state { | ||||
struct resource **res; | struct resource **res; | ||||
struct pcib_softc *sc; | struct pcib_softc *sc; | ||||
int count, error; | int count, error; | ||||
}; | }; | ||||
static void | static void | ||||
alloc_ranges(u_long start, u_long end, void *arg) | alloc_ranges(rman_res_t start, rman_res_t end, void *arg) | ||||
{ | { | ||||
struct alloc_state *as; | struct alloc_state *as; | ||||
struct pcib_window *w; | struct pcib_window *w; | ||||
int rid; | int rid; | ||||
as = arg; | as = arg; | ||||
if (as->error != 0) | if (as->error != 0) | ||||
return; | return; | ||||
w = &as->sc->io; | w = &as->sc->io; | ||||
rid = w->reg; | rid = w->reg; | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(as->sc->dev, | device_printf(as->sc->dev, | ||||
"allocating non-ISA range %#lx-%#lx\n", start, end); | "allocating non-ISA range %#jx-%#jx\n", start, end); | ||||
as->res[as->count] = bus_alloc_resource(as->sc->dev, SYS_RES_IOPORT, | as->res[as->count] = bus_alloc_resource(as->sc->dev, SYS_RES_IOPORT, | ||||
&rid, start, end, end - start + 1, 0); | &rid, start, end, end - start + 1, 0); | ||||
if (as->res[as->count] == NULL) | if (as->res[as->count] == NULL) | ||||
as->error = ENXIO; | as->error = ENXIO; | ||||
else | else | ||||
as->count++; | as->count++; | ||||
} | } | ||||
static int | static int | ||||
pcib_alloc_nonisa_ranges(struct pcib_softc *sc, u_long start, u_long end) | pcib_alloc_nonisa_ranges(struct pcib_softc *sc, rman_res_t start, rman_res_t end) | ||||
{ | { | ||||
struct alloc_state as; | struct alloc_state as; | ||||
int i, new_count; | int i, new_count; | ||||
/* First, see how many ranges we need. */ | /* First, see how many ranges we need. */ | ||||
new_count = 0; | new_count = 0; | ||||
pcib_walk_nonisa_ranges(start, end, count_ranges, &new_count); | pcib_walk_nonisa_ranges(start, end, count_ranges, &new_count); | ||||
Show All 22 Lines | |||||
static void | static void | ||||
pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type, | pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type, | ||||
int flags, pci_addr_t max_address) | int flags, pci_addr_t max_address) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
char buf[64]; | char buf[64]; | ||||
int error, rid; | int error, rid; | ||||
if (max_address != (u_long)max_address) | if (max_address != (rman_res_t)max_address) | ||||
max_address = ~0ul; | max_address = ~(rman_res_t)0; | ||||
w->rman.rm_start = 0; | w->rman.rm_start = 0; | ||||
w->rman.rm_end = max_address; | w->rman.rm_end = max_address; | ||||
w->rman.rm_type = RMAN_ARRAY; | w->rman.rm_type = RMAN_ARRAY; | ||||
snprintf(buf, sizeof(buf), "%s %s window", | snprintf(buf, sizeof(buf), "%s %s window", | ||||
device_get_nameunit(sc->dev), w->name); | device_get_nameunit(sc->dev), w->name); | ||||
w->rman.rm_descr = strdup(buf, M_DEVBUF); | w->rman.rm_descr = strdup(buf, M_DEVBUF); | ||||
error = rman_init(&w->rman); | error = rman_init(&w->rman); | ||||
if (error) | if (error) | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
panic("Failed to initialize %s bus number rman", | panic("Failed to initialize %s bus number rman", | ||||
device_get_nameunit(dev)); | device_get_nameunit(dev)); | ||||
/* | /* | ||||
* Allocate a bus range. This will return an existing bus range | * Allocate a bus range. This will return an existing bus range | ||||
* if one exists, or a new bus range if one does not. | * if one exists, or a new bus range if one does not. | ||||
*/ | */ | ||||
rid = 0; | rid = 0; | ||||
bus->res = bus_alloc_resource(dev, PCI_RES_BUS, &rid, 0ul, ~0ul, | bus->res = bus_alloc_resource(dev, PCI_RES_BUS, &rid, 0, ~0, | ||||
min_count, 0); | min_count, 0); | ||||
if (bus->res == NULL) { | if (bus->res == NULL) { | ||||
/* | /* | ||||
* Fall back to just allocating a range of a single bus | * Fall back to just allocating a range of a single bus | ||||
* number. | * number. | ||||
*/ | */ | ||||
bus->res = bus_alloc_resource(dev, PCI_RES_BUS, &rid, 0ul, ~0ul, | bus->res = bus_alloc_resource(dev, PCI_RES_BUS, &rid, 0, ~0, | ||||
1, 0); | 1, 0); | ||||
} else if (rman_get_size(bus->res) < min_count) | } else if (rman_get_size(bus->res) < min_count) | ||||
/* | /* | ||||
* Attempt to grow the existing range to satisfy the | * Attempt to grow the existing range to satisfy the | ||||
* minimum desired count. | * minimum desired count. | ||||
*/ | */ | ||||
(void)bus_adjust_resource(dev, PCI_RES_BUS, bus->res, | (void)bus_adjust_resource(dev, PCI_RES_BUS, bus->res, | ||||
rman_get_start(bus->res), rman_get_start(bus->res) + | rman_get_start(bus->res), rman_get_start(bus->res) + | ||||
Show All 9 Lines | |||||
panic("Failed to add resource to rman"); | panic("Failed to add resource to rman"); | ||||
bus->sec = rman_get_start(bus->res); | bus->sec = rman_get_start(bus->res); | ||||
bus->sub = rman_get_end(bus->res); | bus->sub = rman_get_end(bus->res); | ||||
} | } | ||||
} | } | ||||
static struct resource * | static struct resource * | ||||
pcib_suballoc_bus(struct pcib_secbus *bus, device_t child, int *rid, | pcib_suballoc_bus(struct pcib_secbus *bus, device_t child, int *rid, | ||||
u_long start, u_long end, u_long count, u_int flags) | rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
res = rman_reserve_resource(&bus->rman, start, end, count, flags, | res = rman_reserve_resource(&bus->rman, start, end, count, flags, | ||||
child); | child); | ||||
if (res == NULL) | if (res == NULL) | ||||
return (NULL); | return (NULL); | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(bus->dev, | device_printf(bus->dev, | ||||
"allocated bus range (%lu-%lu) for rid %d of %s\n", | "allocated bus range (%ju-%ju) for rid %d of %s\n", | ||||
rman_get_start(res), rman_get_end(res), *rid, | rman_get_start(res), rman_get_end(res), *rid, | ||||
pcib_child_name(child)); | pcib_child_name(child)); | ||||
rman_set_rid(res, *rid); | rman_set_rid(res, *rid); | ||||
return (res); | return (res); | ||||
} | } | ||||
/* | /* | ||||
* Attempt to grow the secondary bus range. This is much simpler than | * Attempt to grow the secondary bus range. This is much simpler than | ||||
* for I/O windows as the range can only be grown by increasing | * for I/O windows as the range can only be grown by increasing | ||||
* subbus. | * subbus. | ||||
*/ | */ | ||||
static int | static int | ||||
pcib_grow_subbus(struct pcib_secbus *bus, u_long new_end) | pcib_grow_subbus(struct pcib_secbus *bus, rman_res_t new_end) | ||||
{ | { | ||||
u_long old_end; | rman_res_t old_end; | ||||
int error; | int error; | ||||
old_end = rman_get_end(bus->res); | old_end = rman_get_end(bus->res); | ||||
KASSERT(new_end > old_end, ("attempt to shrink subbus")); | KASSERT(new_end > old_end, ("attempt to shrink subbus")); | ||||
error = bus_adjust_resource(bus->dev, PCI_RES_BUS, bus->res, | error = bus_adjust_resource(bus->dev, PCI_RES_BUS, bus->res, | ||||
rman_get_start(bus->res), new_end); | rman_get_start(bus->res), new_end); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(bus->dev, "grew bus range to %lu-%lu\n", | device_printf(bus->dev, "grew bus range to %ju-%ju\n", | ||||
rman_get_start(bus->res), rman_get_end(bus->res)); | rman_get_start(bus->res), rman_get_end(bus->res)); | ||||
error = rman_manage_region(&bus->rman, old_end + 1, | error = rman_manage_region(&bus->rman, old_end + 1, | ||||
rman_get_end(bus->res)); | rman_get_end(bus->res)); | ||||
if (error) | if (error) | ||||
panic("Failed to add resource to rman"); | panic("Failed to add resource to rman"); | ||||
bus->sub = rman_get_end(bus->res); | bus->sub = rman_get_end(bus->res); | ||||
pci_write_config(bus->dev, bus->sub_reg, bus->sub, 1); | pci_write_config(bus->dev, bus->sub_reg, bus->sub, 1); | ||||
return (0); | return (0); | ||||
} | } | ||||
struct resource * | struct resource * | ||||
pcib_alloc_subbus(struct pcib_secbus *bus, device_t child, int *rid, | pcib_alloc_subbus(struct pcib_secbus *bus, device_t child, int *rid, | ||||
u_long start, u_long end, u_long count, u_int flags) | rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
u_long start_free, end_free, new_end; | rman_res_t start_free, end_free, new_end; | ||||
/* | /* | ||||
* First, see if the request can be satisified by the existing | * First, see if the request can be satisified by the existing | ||||
* bus range. | * bus range. | ||||
*/ | */ | ||||
res = pcib_suballoc_bus(bus, child, rid, start, end, count, flags); | res = pcib_suballoc_bus(bus, child, rid, start, end, count, flags); | ||||
if (res != NULL) | if (res != NULL) | ||||
return (res); | return (res); | ||||
Show All 15 Lines | |||||
* succeeds. | * succeeds. | ||||
*/ | */ | ||||
if (new_end > end) | if (new_end > end) | ||||
return (NULL); | return (NULL); | ||||
/* Finally, attempt to grow the existing resource. */ | /* Finally, attempt to grow the existing resource. */ | ||||
if (bootverbose) { | if (bootverbose) { | ||||
device_printf(bus->dev, | device_printf(bus->dev, | ||||
"attempting to grow bus range for %lu buses\n", count); | "attempting to grow bus range for %ju buses\n", count); | ||||
printf("\tback candidate range: %lu-%lu\n", start_free, | printf("\tback candidate range: %ju-%ju\n", start_free, | ||||
new_end); | new_end); | ||||
} | } | ||||
if (pcib_grow_subbus(bus, new_end) == 0) | if (pcib_grow_subbus(bus, new_end) == 0) | ||||
return (pcib_suballoc_bus(bus, child, rid, start, end, count, | return (pcib_suballoc_bus(bus, child, rid, start, end, count, | ||||
flags)); | flags)); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
#ifdef NEW_PCIB | #ifdef NEW_PCIB | ||||
/* | /* | ||||
* Attempt to allocate a resource from the existing resources assigned | * Attempt to allocate a resource from the existing resources assigned | ||||
* to a window. | * to a window. | ||||
*/ | */ | ||||
static struct resource * | static struct resource * | ||||
pcib_suballoc_resource(struct pcib_softc *sc, struct pcib_window *w, | pcib_suballoc_resource(struct pcib_softc *sc, struct pcib_window *w, | ||||
device_t child, int type, int *rid, u_long start, u_long end, u_long count, | device_t child, int type, int *rid, rman_res_t start, rman_res_t end, | ||||
u_int flags) | rman_res_t count, u_int flags) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
if (!pcib_is_window_open(w)) | if (!pcib_is_window_open(w)) | ||||
return (NULL); | return (NULL); | ||||
res = rman_reserve_resource(&w->rman, start, end, count, | res = rman_reserve_resource(&w->rman, start, end, count, | ||||
flags & ~RF_ACTIVE, child); | flags & ~RF_ACTIVE, child); | ||||
if (res == NULL) | if (res == NULL) | ||||
return (NULL); | return (NULL); | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->dev, | device_printf(sc->dev, | ||||
"allocated %s range (%#lx-%#lx) for rid %x of %s\n", | "allocated %s range (%#jx-%#jx) for rid %x of %s\n", | ||||
w->name, rman_get_start(res), rman_get_end(res), *rid, | w->name, rman_get_start(res), rman_get_end(res), *rid, | ||||
pcib_child_name(child)); | pcib_child_name(child)); | ||||
rman_set_rid(res, *rid); | rman_set_rid(res, *rid); | ||||
/* | /* | ||||
* If the resource should be active, pass that request up the | * If the resource should be active, pass that request up the | ||||
* tree. This assumes the parent drivers can handle | * tree. This assumes the parent drivers can handle | ||||
* activating sub-allocated resources. | * activating sub-allocated resources. | ||||
*/ | */ | ||||
if (flags & RF_ACTIVE) { | if (flags & RF_ACTIVE) { | ||||
if (bus_activate_resource(child, type, *rid, res) != 0) { | if (bus_activate_resource(child, type, *rid, res) != 0) { | ||||
rman_release_resource(res); | rman_release_resource(res); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
} | } | ||||
return (res); | return (res); | ||||
} | } | ||||
/* Allocate a fresh resource range for an unconfigured window. */ | /* Allocate a fresh resource range for an unconfigured window. */ | ||||
static int | static int | ||||
pcib_alloc_new_window(struct pcib_softc *sc, struct pcib_window *w, int type, | pcib_alloc_new_window(struct pcib_softc *sc, struct pcib_window *w, int type, | ||||
u_long start, u_long end, u_long count, u_int flags) | rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
u_long base, limit, wmask; | rman_res_t base, limit, wmask; | ||||
int rid; | int rid; | ||||
/* | /* | ||||
* If this is an I/O window on a bridge with ISA enable set | * If this is an I/O window on a bridge with ISA enable set | ||||
* and the start address is below 64k, then try to allocate an | * and the start address is below 64k, then try to allocate an | ||||
* initial window of 0x1000 bytes long starting at address | * initial window of 0x1000 bytes long starting at address | ||||
* 0xf000 and walking down. Note that if the original request | * 0xf000 and walking down. Note that if the original request | ||||
* was larger than the non-aliased range size of 0x100 our | * was larger than the non-aliased range size of 0x100 our | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
w->base = rman_get_start(res); | w->base = rman_get_start(res); | ||||
w->limit = rman_get_end(res); | w->limit = rman_get_end(res); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* Try to expand an existing window to the requested base and limit. */ | /* Try to expand an existing window to the requested base and limit. */ | ||||
static int | static int | ||||
pcib_expand_window(struct pcib_softc *sc, struct pcib_window *w, int type, | pcib_expand_window(struct pcib_softc *sc, struct pcib_window *w, int type, | ||||
u_long base, u_long limit) | rman_res_t base, rman_res_t limit) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
int error, i, force_64k_base; | int error, i, force_64k_base; | ||||
KASSERT(base <= w->base && limit >= w->limit, | KASSERT(base <= w->base && limit >= w->limit, | ||||
("attempting to shrink window")); | ("attempting to shrink window")); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Attempt to grow a window to make room for a given resource request. | * Attempt to grow a window to make room for a given resource request. | ||||
*/ | */ | ||||
static int | static int | ||||
pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, | pcib_grow_window(struct pcib_softc *sc, struct pcib_window *w, int type, | ||||
u_long start, u_long end, u_long count, u_int flags) | rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) | ||||
{ | { | ||||
u_long align, start_free, end_free, front, back, wmask; | rman_res_t align, start_free, end_free, front, back, wmask; | ||||
int error; | int error; | ||||
/* | /* | ||||
* Clamp the desired resource range to the maximum address | * Clamp the desired resource range to the maximum address | ||||
* this window supports. Reject impossible requests. | * this window supports. Reject impossible requests. | ||||
* | * | ||||
* For I/O port requests behind a bridge with the ISA enable | * For I/O port requests behind a bridge with the ISA enable | ||||
* bit set, force large allocations to start above 64k. | * bit set, force large allocations to start above 64k. | ||||
*/ | */ | ||||
if (!w->valid) | if (!w->valid) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (sc->bridgectl & PCIB_BCR_ISA_ENABLE && count > 0x100 && | if (sc->bridgectl & PCIB_BCR_ISA_ENABLE && count > 0x100 && | ||||
start < 65536) | start < 65536) | ||||
start = 65536; | start = 65536; | ||||
if (end > w->rman.rm_end) | if (end > w->rman.rm_end) | ||||
end = w->rman.rm_end; | end = w->rman.rm_end; | ||||
if (start + count - 1 > end || start + count < start) | if (start + count - 1 > end || start + count < start) | ||||
return (EINVAL); | return (EINVAL); | ||||
wmask = (1ul << w->step) - 1; | wmask = ((rman_res_t)1 << w->step) - 1; | ||||
/* | /* | ||||
* If there is no resource at all, just try to allocate enough | * If there is no resource at all, just try to allocate enough | ||||
* aligned space for this resource. | * aligned space for this resource. | ||||
*/ | */ | ||||
if (w->res == NULL) { | if (w->res == NULL) { | ||||
error = pcib_alloc_new_window(sc, w, type, start, end, count, | error = pcib_alloc_new_window(sc, w, type, start, end, count, | ||||
flags); | flags); | ||||
if (error) { | if (error) { | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->dev, | device_printf(sc->dev, | ||||
"failed to allocate initial %s window (%#lx-%#lx,%#lx)\n", | "failed to allocate initial %s window (%#jx-%#jx,%#jx)\n", | ||||
w->name, start, end, count); | w->name, start, end, count); | ||||
return (error); | return (error); | ||||
} | } | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->dev, | device_printf(sc->dev, | ||||
"allocated initial %s window of %#jx-%#jx\n", | "allocated initial %s window of %#jx-%#jx\n", | ||||
w->name, (uintmax_t)w->base, (uintmax_t)w->limit); | w->name, (uintmax_t)w->base, (uintmax_t)w->limit); | ||||
goto updatewin; | goto updatewin; | ||||
Show All 15 Lines | |||||
* non-alias ranges when it is grown in either direction. | * non-alias ranges when it is grown in either direction. | ||||
* | * | ||||
* XXX: Special case: if w->res is completely empty and the | * XXX: Special case: if w->res is completely empty and the | ||||
* request size is larger than w->res, we should find the | * request size is larger than w->res, we should find the | ||||
* optimal aligned buffer containing w->res and allocate that. | * optimal aligned buffer containing w->res and allocate that. | ||||
*/ | */ | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->dev, | device_printf(sc->dev, | ||||
"attempting to grow %s window for (%#lx-%#lx,%#lx)\n", | "attempting to grow %s window for (%#jx-%#jx,%#jx)\n", | ||||
w->name, start, end, count); | w->name, start, end, count); | ||||
align = 1ul << RF_ALIGNMENT(flags); | align = (rman_res_t)1 << RF_ALIGNMENT(flags); | ||||
if (start < w->base) { | if (start < w->base) { | ||||
if (rman_first_free_region(&w->rman, &start_free, &end_free) != | if (rman_first_free_region(&w->rman, &start_free, &end_free) != | ||||
0 || start_free != w->base) | 0 || start_free != w->base) | ||||
end_free = w->base; | end_free = w->base; | ||||
if (end_free > end) | if (end_free > end) | ||||
end_free = end + 1; | end_free = end + 1; | ||||
/* Move end_free down until it is properly aligned. */ | /* Move end_free down until it is properly aligned. */ | ||||
end_free &= ~(align - 1); | end_free &= ~(align - 1); | ||||
end_free--; | end_free--; | ||||
front = end_free - (count - 1); | front = end_free - (count - 1); | ||||
/* | /* | ||||
* The resource would now be allocated at (front, | * The resource would now be allocated at (front, | ||||
* end_free). Ensure that fits in the (start, end) | * end_free). Ensure that fits in the (start, end) | ||||
* bounds. end_free is checked above. If 'front' is | * bounds. end_free is checked above. If 'front' is | ||||
* ok, ensure it is properly aligned for this window. | * ok, ensure it is properly aligned for this window. | ||||
* Also check for underflow. | * Also check for underflow. | ||||
*/ | */ | ||||
if (front >= start && front <= end_free) { | if (front >= start && front <= end_free) { | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("\tfront candidate range: %#lx-%#lx\n", | printf("\tfront candidate range: %#jx-%#jx\n", | ||||
front, end_free); | front, end_free); | ||||
front &= ~wmask; | front &= ~wmask; | ||||
front = w->base - front; | front = w->base - front; | ||||
} else | } else | ||||
front = 0; | front = 0; | ||||
} else | } else | ||||
front = 0; | front = 0; | ||||
if (end > w->limit) { | if (end > w->limit) { | ||||
Show All 11 Lines | |||||
* The resource would now be allocated at (start_free, | * The resource would now be allocated at (start_free, | ||||
* back). Ensure that fits in the (start, end) | * back). Ensure that fits in the (start, end) | ||||
* bounds. start_free is checked above. If 'back' is | * bounds. start_free is checked above. If 'back' is | ||||
* ok, ensure it is properly aligned for this window. | * ok, ensure it is properly aligned for this window. | ||||
* Also check for overflow. | * Also check for overflow. | ||||
*/ | */ | ||||
if (back <= end && start_free <= back) { | if (back <= end && start_free <= back) { | ||||
if (bootverbose) | if (bootverbose) | ||||
printf("\tback candidate range: %#lx-%#lx\n", | printf("\tback candidate range: %#jx-%#jx\n", | ||||
start_free, back); | start_free, back); | ||||
back |= wmask; | back |= wmask; | ||||
back -= w->limit; | back -= w->limit; | ||||
} else | } else | ||||
back = 0; | back = 0; | ||||
} else | } else | ||||
back = 0; | back = 0; | ||||
Show All 33 Lines | |||||
} | } | ||||
/* | /* | ||||
* We have to trap resource allocation requests and ensure that the bridge | * We have to trap resource allocation requests and ensure that the bridge | ||||
* is set up to, or capable of handling them. | * is set up to, or capable of handling them. | ||||
*/ | */ | ||||
struct resource * | struct resource * | ||||
pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, | pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, | ||||
u_long start, u_long end, u_long count, u_int flags) | rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) | ||||
{ | { | ||||
struct pcib_softc *sc; | struct pcib_softc *sc; | ||||
struct resource *r; | struct resource *r; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
/* | /* | ||||
* VGA resources are decoded iff the VGA enable bit is set in | * VGA resources are decoded iff the VGA enable bit is set in | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
if (sc->flags & PCIB_SUBTRACTIVE && r == NULL) | if (sc->flags & PCIB_SUBTRACTIVE && r == NULL) | ||||
return (bus_generic_alloc_resource(dev, child, type, rid, | return (bus_generic_alloc_resource(dev, child, type, rid, | ||||
start, end, count, flags)); | start, end, count, flags)); | ||||
return (r); | return (r); | ||||
} | } | ||||
int | int | ||||
pcib_adjust_resource(device_t bus, device_t child, int type, struct resource *r, | pcib_adjust_resource(device_t bus, device_t child, int type, struct resource *r, | ||||
u_long start, u_long end) | rman_res_t start, rman_res_t end) | ||||
{ | { | ||||
struct pcib_softc *sc; | struct pcib_softc *sc; | ||||
sc = device_get_softc(bus); | sc = device_get_softc(bus); | ||||
if (pcib_is_resource_managed(sc, type, r)) | if (pcib_is_resource_managed(sc, type, r)) | ||||
return (rman_adjust_resource(r, start, end)); | return (rman_adjust_resource(r, start, end)); | ||||
return (bus_generic_adjust_resource(bus, child, type, r, start, end)); | return (bus_generic_adjust_resource(bus, child, type, r, start, end)); | ||||
} | } | ||||
Show All 18 Lines | |||||
} | } | ||||
#else | #else | ||||
/* | /* | ||||
* We have to trap resource allocation requests and ensure that the bridge | * We have to trap resource allocation requests and ensure that the bridge | ||||
* is set up to, or capable of handling them. | * is set up to, or capable of handling them. | ||||
*/ | */ | ||||
struct resource * | struct resource * | ||||
pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, | pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, | ||||
u_long start, u_long end, u_long count, u_int flags) | rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) | ||||
{ | { | ||||
struct pcib_softc *sc = device_get_softc(dev); | struct pcib_softc *sc = device_get_softc(dev); | ||||
const char *name, *suffix; | const char *name, *suffix; | ||||
int ok; | int ok; | ||||
/* | /* | ||||
* Fail the allocation for this range if it's not supported. | * Fail the allocation for this range if it's not supported. | ||||
*/ | */ | ||||
Show All 33 Lines | |||||
* If we overlap with the subtractive range, then | * If we overlap with the subtractive range, then | ||||
* pick the upper range to use. | * pick the upper range to use. | ||||
*/ | */ | ||||
if (start < sc->iolimit && end > sc->iobase) | if (start < sc->iolimit && end > sc->iobase) | ||||
start = sc->iolimit + 1; | start = sc->iolimit + 1; | ||||
#endif | #endif | ||||
} | } | ||||
if (end < start) { | if (end < start) { | ||||
device_printf(dev, "ioport: end (%lx) < start (%lx)\n", | device_printf(dev, "ioport: end (%jx) < start (%jx)\n", | ||||
end, start); | end, start); | ||||
start = 0; | start = 0; | ||||
end = 0; | end = 0; | ||||
ok = 0; | ok = 0; | ||||
} | } | ||||
if (!ok) { | if (!ok) { | ||||
device_printf(dev, "%s%srequested unsupported I/O " | device_printf(dev, "%s%srequested unsupported I/O " | ||||
"range 0x%lx-0x%lx (decoding 0x%x-0x%x)\n", | "range 0x%jx-0x%jx (decoding 0x%x-0x%x)\n", | ||||
name, suffix, start, end, sc->iobase, sc->iolimit); | name, suffix, start, end, sc->iobase, sc->iolimit); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(dev, | device_printf(dev, | ||||
"%s%srequested I/O range 0x%lx-0x%lx: in range\n", | "%s%srequested I/O range 0x%jx-0x%jx: in range\n", | ||||
name, suffix, start, end); | name, suffix, start, end); | ||||
break; | break; | ||||
case SYS_RES_MEMORY: | case SYS_RES_MEMORY: | ||||
ok = 0; | ok = 0; | ||||
if (pcib_is_nonprefetch_open(sc)) | if (pcib_is_nonprefetch_open(sc)) | ||||
ok = ok || (start >= sc->membase && end <= sc->memlimit); | ok = ok || (start >= sc->membase && end <= sc->memlimit); | ||||
if (pcib_is_prefetch_open(sc)) | if (pcib_is_prefetch_open(sc)) | ||||
Show All 38 Lines | |||||
} | } | ||||
if (pcib_is_prefetch_open(sc)) { | if (pcib_is_prefetch_open(sc)) { | ||||
if (start < sc->pmemlimit && end > sc->pmembase) | if (start < sc->pmemlimit && end > sc->pmembase) | ||||
start = sc->pmemlimit + 1; | start = sc->pmemlimit + 1; | ||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
if (end < start) { | if (end < start) { | ||||
device_printf(dev, "memory: end (%lx) < start (%lx)\n", | device_printf(dev, "memory: end (%jx) < start (%jx)\n", | ||||
end, start); | end, start); | ||||
start = 0; | start = 0; | ||||
end = 0; | end = 0; | ||||
ok = 0; | ok = 0; | ||||
} | } | ||||
if (!ok && bootverbose) | if (!ok && bootverbose) | ||||
device_printf(dev, | device_printf(dev, | ||||
"%s%srequested unsupported memory range %#lx-%#lx " | "%s%srequested unsupported memory range %#jx-%#jx " | ||||
"(decoding %#jx-%#jx, %#jx-%#jx)\n", | "(decoding %#jx-%#jx, %#jx-%#jx)\n", | ||||
name, suffix, start, end, | name, suffix, start, end, | ||||
(uintmax_t)sc->membase, (uintmax_t)sc->memlimit, | (uintmax_t)sc->membase, (uintmax_t)sc->memlimit, | ||||
(uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit); | (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit); | ||||
if (!ok) | if (!ok) | ||||
return (NULL); | return (NULL); | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(dev,"%s%srequested memory range " | device_printf(dev,"%s%srequested memory range " | ||||
"0x%lx-0x%lx: good\n", | "0x%jx-0x%jx: good\n", | ||||
name, suffix, start, end); | name, suffix, start, end); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
/* | /* | ||||
* Bridge is OK decoding this resource, so pass it up. | * Bridge is OK decoding this resource, so pass it up. | ||||
▲ Show 20 Lines • Show All 42 Lines • Show Last 20 Lines |