Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/ofw/ofw_real.c
Show First 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | static MALLOC_DEFINE(M_OFWREAL, "ofwreal", | ||||
"Open Firmware Real Mode Bounce Page"); | "Open Firmware Real Mode Bounce Page"); | ||||
static int (*openfirmware)(void *); | static int (*openfirmware)(void *); | ||||
static vm_offset_t of_bounce_phys; | static vm_offset_t of_bounce_phys; | ||||
static caddr_t of_bounce_virt; | static caddr_t of_bounce_virt; | ||||
static off_t of_bounce_offset; | static off_t of_bounce_offset; | ||||
static size_t of_bounce_size; | static size_t of_bounce_size; | ||||
static struct mtx of_bounce_mtx; | static struct mtx of_bounce_mtx; | ||||
static struct mtx of_spin_mtx; | |||||
static struct mtx *of_real_mtx; | |||||
static void (*of_mtx_lock)(void); | |||||
static void (*of_mtx_unlock)(void); | |||||
extern int ofw_real_mode; | extern int ofw_real_mode; | ||||
/* | /* | ||||
* After the VM is up, allocate a wired, low memory bounce page. | * After the VM is up, allocate a wired, low memory bounce page. | ||||
*/ | */ | ||||
static void ofw_real_bounce_alloc(void *); | static void ofw_real_bounce_alloc(void *); | ||||
SYSINIT(ofw_real_bounce_alloc, SI_SUB_KMEM, SI_ORDER_ANY, | SYSINIT(ofw_real_bounce_alloc, SI_SUB_KMEM, SI_ORDER_ANY, | ||||
ofw_real_bounce_alloc, NULL); | ofw_real_bounce_alloc, NULL); | ||||
static void | static void | ||||
ofw_real_mtx_lock_spin(void) | |||||
{ | |||||
mtx_lock_spin(of_real_mtx); | |||||
} | |||||
static void | |||||
ofw_real_mtx_lock(void) | |||||
{ | |||||
mtx_lock(of_real_mtx); | |||||
} | |||||
static void | |||||
ofw_real_mtx_unlock_spin(void) | |||||
{ | |||||
mtx_unlock_spin(of_real_mtx); | |||||
} | |||||
static void | |||||
ofw_real_mtx_unlock(void) | |||||
{ | |||||
mtx_lock(of_real_mtx); | |||||
} | |||||
static void | |||||
ofw_real_start(void) | ofw_real_start(void) | ||||
{ | { | ||||
mtx_lock(&of_bounce_mtx); | (*of_mtx_lock)(); | ||||
of_bounce_offset = 0; | of_bounce_offset = 0; | ||||
} | } | ||||
static void | static void | ||||
ofw_real_stop(void) | ofw_real_stop(void) | ||||
{ | { | ||||
mtx_unlock(&of_bounce_mtx); | (*of_mtx_unlock)(); | ||||
} | } | ||||
static void | static void | ||||
ofw_real_bounce_alloc(void *junk) | ofw_real_bounce_alloc(void *junk) | ||||
{ | { | ||||
caddr_t temp; | caddr_t temp; | ||||
/* | /* | ||||
Show All 20 Lines | ofw_real_bounce_alloc(void *junk) | ||||
of_bounce_phys = vtophys(of_bounce_virt); | of_bounce_phys = vtophys(of_bounce_virt); | ||||
of_bounce_size = 4 * PAGE_SIZE; | of_bounce_size = 4 * PAGE_SIZE; | ||||
/* | /* | ||||
* For virtual-mode OF, direct map this physical address so that | * For virtual-mode OF, direct map this physical address so that | ||||
* we have a 32-bit virtual address to give OF. | * we have a 32-bit virtual address to give OF. | ||||
*/ | */ | ||||
if (!ofw_real_mode && (!hw_direct_map || DMAP_BASE_ADDRESS != 0)) | if (!ofw_real_mode && (!hw_direct_map || DMAP_BASE_ADDRESS != 0)) | ||||
pmap_kenter(of_bounce_phys, of_bounce_phys); | pmap_kenter(of_bounce_phys, of_bounce_phys); | ||||
mtx_unlock(&of_bounce_mtx); | mtx_unlock(&of_bounce_mtx); | ||||
} | } | ||||
static cell_t | static cell_t | ||||
ofw_real_map(const void *buf, size_t len) | ofw_real_map(const void *buf, size_t len) | ||||
{ | { | ||||
static char emergency_buffer[255]; | static char emergency_buffer[255]; | ||||
cell_t phys; | cell_t phys; | ||||
mtx_assert(&of_bounce_mtx, MA_OWNED); | mtx_assert(of_real_mtx, MA_OWNED); | ||||
if (of_bounce_virt == NULL) { | if (of_bounce_virt == NULL) { | ||||
/* | /* | ||||
* If we haven't set up the MMU, then buf is guaranteed | * If we haven't set up the MMU, then buf is guaranteed | ||||
* to be accessible to OF, because the only memory we | * to be accessible to OF, because the only memory we | ||||
* can use right now is memory mapped by firmware. | * can use right now is memory mapped by firmware. | ||||
*/ | */ | ||||
if (!pmap_bootstrapped) | if (!pmap_bootstrapped) | ||||
Show All 33 Lines | ofw_real_map(const void *buf, size_t len) | ||||
of_bounce_offset += len; | of_bounce_offset += len; | ||||
return (phys); | return (phys); | ||||
} | } | ||||
static void | static void | ||||
ofw_real_unmap(cell_t physaddr, void *buf, size_t len) | ofw_real_unmap(cell_t physaddr, void *buf, size_t len) | ||||
{ | { | ||||
mtx_assert(&of_bounce_mtx, MA_OWNED); | mtx_assert(of_real_mtx, MA_OWNED); | ||||
if (of_bounce_virt == NULL) | if (of_bounce_virt == NULL) | ||||
return; | return; | ||||
if (physaddr == 0) | if (physaddr == 0) | ||||
return; | return; | ||||
memcpy(buf,of_bounce_virt + (physaddr - of_bounce_phys),len); | memcpy(buf,of_bounce_virt + (physaddr - of_bounce_phys),len); | ||||
} | } | ||||
/* Initialiser */ | /* Initialiser */ | ||||
static int | static int | ||||
ofw_real_init(ofw_t ofw, void *openfirm) | ofw_real_init(ofw_t ofw, void *openfirm) | ||||
{ | { | ||||
openfirmware = (int (*)(void *))openfirm; | int mtx_spin; | ||||
openfirmware = (int (*)(void *))openfirm; | |||||
mtx_init(&of_bounce_mtx, "OF Bounce Page", NULL, MTX_DEF); | mtx_init(&of_bounce_mtx, "OF Bounce Page", NULL, MTX_DEF); | ||||
mtx_spin = 0; | |||||
TUNABLE_INT_FETCH("hw.ofw.mtx_spin", &mtx_spin); | |||||
jhibbits: I think this should be a "machdep." tunable, now "hw.". | |||||
if (mtx_spin) { | |||||
mtx_init(&of_spin_mtx, "OF Real", NULL, MTX_SPIN); | |||||
of_real_mtx = &of_spin_mtx; | |||||
of_mtx_lock = ofw_real_mtx_lock_spin; | |||||
of_mtx_unlock = ofw_real_mtx_unlock_spin; | |||||
} else { | |||||
of_real_mtx = &of_bounce_mtx; | |||||
of_mtx_lock = ofw_real_mtx_lock; | |||||
of_mtx_unlock = ofw_real_mtx_unlock; | |||||
} | |||||
of_bounce_virt = NULL; | of_bounce_virt = NULL; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Generic functions | * Generic functions | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 791 Lines • Show Last 20 Lines |
I think this should be a "machdep." tunable, now "hw.".