A few simple changes:
- Use an extent map to manage the ISA memory "hole", much like how i/o port space is manged with an extent map. Do the actual accounting in bus_mem_{,un}map(). - When creating the ioport and iomem extent maps, pass the EX_NOBLOB flag, which tells the extent map code to disallow fragmenting of regions. This will make it easier to catch simple i/o and memory mapping bugs (like the if_ed.c bug I just fixed) in the future. - In bus_mem_map(), a chunk of code was indented using spaces. Make the indentation use tabs. - In bus_io_unmap(), fix the format passed to printf().
This commit is contained in:
parent
794614df64
commit
698844254e
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.204 1996/06/23 19:59:16 thorpej Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.205 1996/06/25 21:22:48 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994, 1995, 1996 Charles M. Hannum. All rights reserved.
|
||||
@ -147,12 +147,15 @@ static vm_offset_t hole_start, hole_end;
|
||||
static vm_offset_t avail_next;
|
||||
|
||||
/*
|
||||
* Extent map to manage I/O space. Allocate storage for 8 regions,
|
||||
* initially. Later, ioport_malloc_safe will indicate that it's
|
||||
* safe to use malloc() to dynamically allocate region descriptors.
|
||||
* Extent maps to manage I/O and ISA memory hole space. Allocate
|
||||
* storage for 8 regions in each, initially. Later, ioport_malloc_safe
|
||||
* will indicate that it's safe to use malloc() to dynamically allocate
|
||||
* region descriptors.
|
||||
*/
|
||||
static char ioport_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)];
|
||||
static char iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)];
|
||||
static struct extent *ioport_ex;
|
||||
static struct extent *iomem_ex;
|
||||
static ioport_malloc_safe;
|
||||
|
||||
caddr_t allocsys __P((caddr_t));
|
||||
@ -1074,10 +1077,17 @@ init386(first_avail)
|
||||
proc0.p_addr = proc0paddr;
|
||||
|
||||
/*
|
||||
* Initialize the I/O port extent map.
|
||||
* Initialize the I/O port and I/O mem extent maps.
|
||||
* Note: we don't have to check the return value since
|
||||
* creation of a fixed extent map will never fail (since
|
||||
* descriptor storage has already been allocated).
|
||||
*/
|
||||
ioport_ex = extent_create("ioport", 0x0, 0xffff, M_DEVBUF,
|
||||
ioport_ex_storage, sizeof(ioport_ex_storage), EX_NOWAIT);
|
||||
ioport_ex_storage, sizeof(ioport_ex_storage),
|
||||
EX_NOBLOB|EX_NOWAIT);
|
||||
iomem_ex = extent_create("iomem", 0x0a0000, 0x100000, M_DEVBUF,
|
||||
iomem_ex_storage, sizeof(iomem_ex_storage),
|
||||
EX_NOBLOB|EX_NOWAIT);
|
||||
|
||||
consinit(); /* XXX SHOULD NOT BE DONE HERE */
|
||||
|
||||
@ -1410,6 +1420,23 @@ bus_mem_map(t, bpa, size, cacheable, mhp)
|
||||
{
|
||||
u_long pa, endpa;
|
||||
vm_offset_t va;
|
||||
int error, did_extent_alloc = 0;
|
||||
|
||||
/*
|
||||
* Before we go any further, let's make sure that this
|
||||
* memory region is available.
|
||||
*
|
||||
* XXX We check for free space if the requested region
|
||||
* XXX only if the request is within the ISA memory hole.
|
||||
* XXX This is arguably bogus.
|
||||
*/
|
||||
if (bpa >= iomem_ex->ex_start && bpa < iomem_ex->ex_end) {
|
||||
error = extent_alloc_region(iomem_ex, bpa, size,
|
||||
EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0));
|
||||
if (error)
|
||||
return (error);
|
||||
did_extent_alloc = 1;
|
||||
}
|
||||
|
||||
pa = i386_trunc_page(bpa);
|
||||
endpa = i386_round_page((bpa + size) - 1);
|
||||
@ -1420,20 +1447,30 @@ bus_mem_map(t, bpa, size, cacheable, mhp)
|
||||
#endif
|
||||
|
||||
va = kmem_alloc_pageable(kernel_map, endpa - pa);
|
||||
if (va == 0)
|
||||
if (va == 0) {
|
||||
if (did_extent_alloc) {
|
||||
if (extent_free(iomem_ex, bpa, size, EX_NOWAIT |
|
||||
(ioport_malloc_safe ? EX_MALLOCOK : 0))) {
|
||||
/* XXX panic? */
|
||||
printf("bus_mem_map: pa 0x%lx, size 0x%lx\n",
|
||||
bpa, size);
|
||||
printf("bus_mem_map: can't free region\n");
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
*mhp = (caddr_t)(va + (bpa & PGOFSET));
|
||||
|
||||
for (; pa < endpa; pa += NBPG, va += NBPG) {
|
||||
pmap_enter(pmap_kernel(), va, pa, VM_PROT_READ | VM_PROT_WRITE,
|
||||
TRUE);
|
||||
if (!cacheable)
|
||||
pmap_changebit(pa, PG_N, ~0);
|
||||
else
|
||||
pmap_changebit(pa, 0, ~PG_N);
|
||||
}
|
||||
pmap_enter(pmap_kernel(), va, pa, VM_PROT_READ | VM_PROT_WRITE,
|
||||
TRUE);
|
||||
if (!cacheable)
|
||||
pmap_changebit(pa, PG_N, ~0);
|
||||
else
|
||||
pmap_changebit(pa, 0, ~PG_N);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1443,6 +1480,7 @@ bus_mem_unmap(t, memh, size)
|
||||
bus_mem_size_t size;
|
||||
{
|
||||
vm_offset_t va, endva;
|
||||
bus_mem_addr_t bpa;
|
||||
|
||||
va = i386_trunc_page(memh);
|
||||
endva = i386_round_page((memh + size) - 1);
|
||||
@ -1452,6 +1490,23 @@ bus_mem_unmap(t, memh, size)
|
||||
panic("bus_mem_unmap: overflow");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find the PA the mapping corresponds to and free that
|
||||
* region from the iomem extent map.
|
||||
*
|
||||
* XXX We only do this for regions that lie within the
|
||||
* XXX ISA memory hole. This is arguably bogus.
|
||||
*/
|
||||
bpa = pmap_extract(pmap_kernel(), va) + ((u_long)memh & PGOFSET);
|
||||
if (bpa >= iomem_ex->ex_start && bpa < iomem_ex->ex_end) {
|
||||
if (extent_free(iomem_ex, bpa, size,
|
||||
EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
|
||||
printf("bus_mem_unmap: pa 0x%lx, size 0x%lx\n",
|
||||
memh, size);
|
||||
printf("bus_mem_unmap: can't free region\n");
|
||||
}
|
||||
}
|
||||
|
||||
kmem_free(kernel_map, va, endva - va);
|
||||
}
|
||||
|
||||
@ -1486,7 +1541,7 @@ bus_io_unmap(t, ioh, size)
|
||||
error = extent_free(ioport_ex, ioh, size,
|
||||
EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0));
|
||||
if (error) {
|
||||
printf("bus_io_unmap: port 0x%x, size 0x%x\n",
|
||||
printf("bus_io_unmap: port 0x%lx, size 0x%lx\n",
|
||||
ioh, size);
|
||||
printf("bus_io_unmap: can't free region\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user