summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoriwasaki <iwasaki@FreeBSD.org>2001-11-11 15:51:30 +0000
committeriwasaki <iwasaki@FreeBSD.org>2001-11-11 15:51:30 +0000
commit11db8ee1270df517bbbe56c47345e46505f25ad7 (patch)
treea0107f7ed635a7eaaf1151021647fa961d4de924 /sys
parent81a7064bff0d2ad670703950289dd0607f99b4cc (diff)
downloadFreeBSD-src-11db8ee1270df517bbbe56c47345e46505f25ad7.zip
FreeBSD-src-11db8ee1270df517bbbe56c47345e46505f25ad7.tar.gz
Add two minor changes.
- clean up wakeup routing fixup code by using macros. - allocate pte object temporary for kernel thread to avoid kernel panic by events from sleep button or lid switch.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/acpica/acpi_wakeup.c77
-rw-r--r--sys/i386/acpica/acpi_wakeup.c77
2 files changed, 88 insertions, 66 deletions
diff --git a/sys/amd64/acpica/acpi_wakeup.c b/sys/amd64/acpica/acpi_wakeup.c
index 3ba70b1..3c9e0cd 100644
--- a/sys/amd64/acpica/acpi_wakeup.c
+++ b/sys/amd64/acpica/acpi_wakeup.c
@@ -39,6 +39,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
+#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
@@ -165,16 +166,28 @@ acpi_printcpu(void)
r_cs, r_ds, r_es, r_fs, r_gs, r_ss);
}
+#define WAKECODE_FIXUP(offset, type, val) do { \
+ void **addr; \
+ addr = (void **)(sc->acpi_wakeaddr + offset); \
+ (type *)*addr = val; \
+} while (0)
+
+#define WAKECODE_BCOPY(offset, type, val) do { \
+ void **addr; \
+ addr = (void **)(sc->acpi_wakeaddr + offset); \
+ bcopy(&(val), addr, sizeof(type)); \
+} while (0)
+
int
acpi_sleep_machdep(struct acpi_softc *sc, int state)
{
ACPI_STATUS status;
- void **addr;
vm_offset_t oldphys;
struct pmap *pm;
vm_page_t page;
static vm_page_t opage = NULL;
int ret = 0;
+ int pteobj_allocated = 0;
u_long ef;
if (sc->acpi_wakeaddr == NULL) {
@@ -187,7 +200,12 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
disable_intr();
/* Create Identity Mapping */
- pm = &CURPROC->p_vmspace->vm_pmap;
+ pm = vmspace_pmap(CURPROC->p_vmspace);
+ if (pm->pm_pteobj == NULL) {
+ pm->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, PTDPTDI + 1);
+ pteobj_allocated = 1;
+ }
+
oldphys = pmap_extract(pm, sc->acpi_wakephys);
if (oldphys) {
opage = PHYS_TO_VM_PAGE(oldphys);
@@ -202,37 +220,25 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
p_gdt = (struct region_descriptor *)(sc->acpi_wakeaddr + physical_gdt);
p_gdt->rd_limit = r_gdt.rd_limit;
p_gdt->rd_base = vtophys(r_gdt.rd_base);
- addr = (void **)(sc->acpi_wakeaddr + physical_esp);
- (u_int32_t *)*addr = vtophys(r_esp);
- addr = (void **)(sc->acpi_wakeaddr + previous_cr0);
- (u_int32_t *)*addr = r_cr0;
- addr = (void **)(sc->acpi_wakeaddr + previous_cr2);
- (u_int32_t *)*addr = r_cr2;
- addr = (void **)(sc->acpi_wakeaddr + previous_cr3);
- (u_int32_t *)*addr = r_cr3;
- addr = (void **)(sc->acpi_wakeaddr + previous_cr4);
- (u_int32_t *)*addr = r_cr4;
-
- addr = (void **)(sc->acpi_wakeaddr + previous_tr);
- (u_int16_t *)*addr = r_tr;
- addr = (void **)(sc->acpi_wakeaddr + previous_gdt);
- bcopy(&r_gdt, addr, sizeof(r_gdt));
- addr = (void **)(sc->acpi_wakeaddr + previous_ldt);
- (u_int16_t *)*addr = r_ldt;
- addr = (void **)(sc->acpi_wakeaddr + previous_idt);
- bcopy(&r_idt, addr, sizeof(r_idt));
- addr = (void **)(sc->acpi_wakeaddr + where_to_recover);
- *addr = acpi_restorecpu;
- addr = (void **)(sc->acpi_wakeaddr + previous_ds);
- (u_int16_t *)*addr = r_ds;
- addr = (void **)(sc->acpi_wakeaddr + previous_es);
- (u_int16_t *)*addr = r_es;
- addr = (void **)(sc->acpi_wakeaddr + previous_fs);
- (u_int16_t *)*addr = r_fs;
- addr = (void **)(sc->acpi_wakeaddr + previous_gs);
- (u_int16_t *)*addr = r_gs;
- addr = (void **)(sc->acpi_wakeaddr + previous_ss);
- (u_int16_t *)*addr = r_ss;
+
+ WAKECODE_FIXUP(physical_esp, u_int32_t, vtophys(r_esp));
+ WAKECODE_FIXUP(previous_cr0, u_int32_t, r_cr0);
+ WAKECODE_FIXUP(previous_cr2, u_int32_t, r_cr2);
+ WAKECODE_FIXUP(previous_cr3, u_int32_t, r_cr3);
+ WAKECODE_FIXUP(previous_cr4, u_int32_t, r_cr4);
+
+ WAKECODE_FIXUP(previous_tr, u_int16_t, r_tr);
+ WAKECODE_BCOPY(previous_gdt, struct region_descriptor, r_gdt);
+ WAKECODE_FIXUP(previous_ldt, u_int16_t, r_ldt);
+ WAKECODE_BCOPY(previous_idt, struct region_descriptor, r_idt);
+
+ WAKECODE_FIXUP(where_to_recover, void, acpi_restorecpu);
+
+ WAKECODE_FIXUP(previous_ds, u_int16_t, r_ds);
+ WAKECODE_FIXUP(previous_es, u_int16_t, r_es);
+ WAKECODE_FIXUP(previous_fs, u_int16_t, r_fs);
+ WAKECODE_FIXUP(previous_gs, u_int16_t, r_gs);
+ WAKECODE_FIXUP(previous_ss, u_int16_t, r_ss);
if (debug_wakeup) {
acpi_printcpu();
@@ -274,6 +280,11 @@ out:
VM_PROT_READ | VM_PROT_WRITE, 0);
}
+ if (pteobj_allocated) {
+ vm_object_deallocate(pm->pm_pteobj);
+ pm->pm_pteobj = NULL;
+ }
+
write_eflags(ef);
return (ret);
diff --git a/sys/i386/acpica/acpi_wakeup.c b/sys/i386/acpica/acpi_wakeup.c
index 3ba70b1..3c9e0cd 100644
--- a/sys/i386/acpica/acpi_wakeup.c
+++ b/sys/i386/acpica/acpi_wakeup.c
@@ -39,6 +39,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
+#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
@@ -165,16 +166,28 @@ acpi_printcpu(void)
r_cs, r_ds, r_es, r_fs, r_gs, r_ss);
}
+#define WAKECODE_FIXUP(offset, type, val) do { \
+ void **addr; \
+ addr = (void **)(sc->acpi_wakeaddr + offset); \
+ (type *)*addr = val; \
+} while (0)
+
+#define WAKECODE_BCOPY(offset, type, val) do { \
+ void **addr; \
+ addr = (void **)(sc->acpi_wakeaddr + offset); \
+ bcopy(&(val), addr, sizeof(type)); \
+} while (0)
+
int
acpi_sleep_machdep(struct acpi_softc *sc, int state)
{
ACPI_STATUS status;
- void **addr;
vm_offset_t oldphys;
struct pmap *pm;
vm_page_t page;
static vm_page_t opage = NULL;
int ret = 0;
+ int pteobj_allocated = 0;
u_long ef;
if (sc->acpi_wakeaddr == NULL) {
@@ -187,7 +200,12 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
disable_intr();
/* Create Identity Mapping */
- pm = &CURPROC->p_vmspace->vm_pmap;
+ pm = vmspace_pmap(CURPROC->p_vmspace);
+ if (pm->pm_pteobj == NULL) {
+ pm->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, PTDPTDI + 1);
+ pteobj_allocated = 1;
+ }
+
oldphys = pmap_extract(pm, sc->acpi_wakephys);
if (oldphys) {
opage = PHYS_TO_VM_PAGE(oldphys);
@@ -202,37 +220,25 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
p_gdt = (struct region_descriptor *)(sc->acpi_wakeaddr + physical_gdt);
p_gdt->rd_limit = r_gdt.rd_limit;
p_gdt->rd_base = vtophys(r_gdt.rd_base);
- addr = (void **)(sc->acpi_wakeaddr + physical_esp);
- (u_int32_t *)*addr = vtophys(r_esp);
- addr = (void **)(sc->acpi_wakeaddr + previous_cr0);
- (u_int32_t *)*addr = r_cr0;
- addr = (void **)(sc->acpi_wakeaddr + previous_cr2);
- (u_int32_t *)*addr = r_cr2;
- addr = (void **)(sc->acpi_wakeaddr + previous_cr3);
- (u_int32_t *)*addr = r_cr3;
- addr = (void **)(sc->acpi_wakeaddr + previous_cr4);
- (u_int32_t *)*addr = r_cr4;
-
- addr = (void **)(sc->acpi_wakeaddr + previous_tr);
- (u_int16_t *)*addr = r_tr;
- addr = (void **)(sc->acpi_wakeaddr + previous_gdt);
- bcopy(&r_gdt, addr, sizeof(r_gdt));
- addr = (void **)(sc->acpi_wakeaddr + previous_ldt);
- (u_int16_t *)*addr = r_ldt;
- addr = (void **)(sc->acpi_wakeaddr + previous_idt);
- bcopy(&r_idt, addr, sizeof(r_idt));
- addr = (void **)(sc->acpi_wakeaddr + where_to_recover);
- *addr = acpi_restorecpu;
- addr = (void **)(sc->acpi_wakeaddr + previous_ds);
- (u_int16_t *)*addr = r_ds;
- addr = (void **)(sc->acpi_wakeaddr + previous_es);
- (u_int16_t *)*addr = r_es;
- addr = (void **)(sc->acpi_wakeaddr + previous_fs);
- (u_int16_t *)*addr = r_fs;
- addr = (void **)(sc->acpi_wakeaddr + previous_gs);
- (u_int16_t *)*addr = r_gs;
- addr = (void **)(sc->acpi_wakeaddr + previous_ss);
- (u_int16_t *)*addr = r_ss;
+
+ WAKECODE_FIXUP(physical_esp, u_int32_t, vtophys(r_esp));
+ WAKECODE_FIXUP(previous_cr0, u_int32_t, r_cr0);
+ WAKECODE_FIXUP(previous_cr2, u_int32_t, r_cr2);
+ WAKECODE_FIXUP(previous_cr3, u_int32_t, r_cr3);
+ WAKECODE_FIXUP(previous_cr4, u_int32_t, r_cr4);
+
+ WAKECODE_FIXUP(previous_tr, u_int16_t, r_tr);
+ WAKECODE_BCOPY(previous_gdt, struct region_descriptor, r_gdt);
+ WAKECODE_FIXUP(previous_ldt, u_int16_t, r_ldt);
+ WAKECODE_BCOPY(previous_idt, struct region_descriptor, r_idt);
+
+ WAKECODE_FIXUP(where_to_recover, void, acpi_restorecpu);
+
+ WAKECODE_FIXUP(previous_ds, u_int16_t, r_ds);
+ WAKECODE_FIXUP(previous_es, u_int16_t, r_es);
+ WAKECODE_FIXUP(previous_fs, u_int16_t, r_fs);
+ WAKECODE_FIXUP(previous_gs, u_int16_t, r_gs);
+ WAKECODE_FIXUP(previous_ss, u_int16_t, r_ss);
if (debug_wakeup) {
acpi_printcpu();
@@ -274,6 +280,11 @@ out:
VM_PROT_READ | VM_PROT_WRITE, 0);
}
+ if (pteobj_allocated) {
+ vm_object_deallocate(pm->pm_pteobj);
+ pm->pm_pteobj = NULL;
+ }
+
write_eflags(ef);
return (ret);
OpenPOWER on IntegriCloud