svn commit: r239014 - in user/mjacob/sys: conf dev/esp dev/isp
geom/multipath kern netgraph powerpc/powerpc x86/x86
Matt Jacob
mjacob at FreeBSD.org
Fri Aug 3 15:29:20 UTC 2012
Author: mjacob
Date: Fri Aug 3 15:29:19 2012
New Revision: 239014
URL: http://svn.freebsd.org/changeset/base/239014
Log:
MFC at 239013
Modified:
user/mjacob/sys/conf/files
user/mjacob/sys/dev/esp/ncr53c9x.c
user/mjacob/sys/dev/isp/isp_pci.c
user/mjacob/sys/geom/multipath/g_multipath.c
user/mjacob/sys/kern/kern_clocksource.c
user/mjacob/sys/netgraph/ng_pptpgre.c
user/mjacob/sys/powerpc/powerpc/busdma_machdep.c
user/mjacob/sys/x86/x86/busdma_machdep.c
user/mjacob/sys/x86/x86/local_apic.c
Directory Properties:
user/mjacob/sys/ (props changed)
user/mjacob/sys/conf/ (props changed)
Modified: user/mjacob/sys/conf/files
==============================================================================
--- user/mjacob/sys/conf/files Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/conf/files Fri Aug 3 15:29:19 2012 (r239014)
@@ -2213,6 +2213,16 @@ dev/utopia/idtphy.c optional utopia
dev/utopia/suni.c optional utopia
dev/utopia/utopia.c optional utopia
dev/vge/if_vge.c optional vge
+#
+# virtio support
+#
+dev/virtio/pci/virtio_pci.c optional vtnet
+dev/virtio/virtio.c optional vtnet
+dev/virtio/virtqueue.c optional vtnet
+dev/virtio/network/if_vtnet.c optional vtnet
+dev/virtio/virtio_bus_if.m optional vtnet
+dev/virtio/virtio_if.m optional vtnet
+
dev/vkbd/vkbd.c optional vkbd
dev/vr/if_vr.c optional vr pci
dev/vte/if_vte.c optional vte pci
Modified: user/mjacob/sys/dev/esp/ncr53c9x.c
==============================================================================
--- user/mjacob/sys/dev/esp/ncr53c9x.c Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/dev/esp/ncr53c9x.c Fri Aug 3 15:29:19 2012 (r239014)
@@ -2038,6 +2038,10 @@ gotit:
}
break;
+ case MSG_IGN_WIDE_RESIDUE:
+ NCR_MSGS(("ignore_wide_residue "));
+ break;
+
default:
NCR_MSGS(("ident "));
xpt_print_path(ecb->ccb->ccb_h.path);
Modified: user/mjacob/sys/dev/isp/isp_pci.c
==============================================================================
--- user/mjacob/sys/dev/isp/isp_pci.c Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/dev/isp/isp_pci.c Fri Aug 3 15:29:19 2012 (r239014)
@@ -1482,16 +1482,18 @@ imc(void *arg, bus_dma_segment_t *segs,
segs->ds_addr += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(imushp->isp));
imushp->vbase += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(imushp->isp));
- imushp->isp->isp_osinfo.ecmd_dma = segs->ds_addr;
- imushp->isp->isp_osinfo.ecmd_free = (isp_ecmd_t *)imushp->vbase;
- imushp->isp->isp_osinfo.ecmd_base = imushp->isp->isp_osinfo.ecmd_free;
- for (ecmd = imushp->isp->isp_osinfo.ecmd_free; ecmd < &imushp->isp->isp_osinfo.ecmd_free[N_XCMDS]; ecmd++) {
- if (ecmd == &imushp->isp->isp_osinfo.ecmd_free[N_XCMDS - 1]) {
- ecmd->next = NULL;
- } else {
- ecmd->next = ecmd + 1;
- }
- }
+ if (imushp->isp->isp_type >= ISP_HA_FC_2300) {
+ imushp->isp->isp_osinfo.ecmd_dma = segs->ds_addr;
+ imushp->isp->isp_osinfo.ecmd_free = (isp_ecmd_t *)imushp->vbase;
+ imushp->isp->isp_osinfo.ecmd_base = imushp->isp->isp_osinfo.ecmd_free;
+ for (ecmd = imushp->isp->isp_osinfo.ecmd_free; ecmd < &imushp->isp->isp_osinfo.ecmd_free[N_XCMDS]; ecmd++) {
+ if (ecmd == &imushp->isp->isp_osinfo.ecmd_free[N_XCMDS - 1]) {
+ ecmd->next = NULL;
+ } else {
+ ecmd->next = ecmd + 1;
+ }
+ }
+ }
#ifdef ISP_TARGET_MODE
segs->ds_addr += (N_XCMDS * XCMD_SIZE);
imushp->vbase += (N_XCMDS * XCMD_SIZE);
Modified: user/mjacob/sys/geom/multipath/g_multipath.c
==============================================================================
--- user/mjacob/sys/geom/multipath/g_multipath.c Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/geom/multipath/g_multipath.c Fri Aug 3 15:29:19 2012 (r239014)
@@ -849,6 +849,78 @@ g_multipath_ctl_add_name(struct gctl_req
}
static void
+g_multipath_ctl_prefer(struct gctl_req *req, struct g_class *mp)
+{
+ struct g_geom *gp;
+ struct g_multipath_softc *sc;
+ struct g_consumer *cp;
+ const char *name, *mpname;
+ static const char devpf[6] = "/dev/";
+ int *nargs;
+
+ g_topology_assert();
+
+ mpname = gctl_get_asciiparam(req, "arg0");
+ if (mpname == NULL) {
+ gctl_error(req, "No 'arg0' argument");
+ return;
+ }
+ gp = g_multipath_find_geom(mp, mpname);
+ if (gp == NULL) {
+ gctl_error(req, "Device %s is invalid", mpname);
+ return;
+ }
+ sc = gp->softc;
+
+ nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
+ if (nargs == NULL) {
+ gctl_error(req, "No 'nargs' argument");
+ return;
+ }
+ if (*nargs != 2) {
+ gctl_error(req, "missing device");
+ return;
+ }
+
+ name = gctl_get_asciiparam(req, "arg1");
+ if (name == NULL) {
+ gctl_error(req, "No 'arg1' argument");
+ return;
+ }
+ if (strncmp(name, devpf, 5) == 0) {
+ name += 5;
+ }
+
+ LIST_FOREACH(cp, &gp->consumer, consumer) {
+ if (cp->provider != NULL
+ && strcmp(cp->provider->name, name) == 0)
+ break;
+ }
+
+ if (cp == NULL) {
+ gctl_error(req, "Provider %s not found", name);
+ return;
+ }
+
+ mtx_lock(&sc->sc_mtx);
+
+ if (cp->index & MP_BAD) {
+ gctl_error(req, "Consumer %s is invalid", name);
+ mtx_unlock(&sc->sc_mtx);
+ return;
+ }
+
+ /* Here when the consumer is present and in good shape */
+
+ sc->sc_active = cp;
+ if (!sc->sc_active_active)
+ printf("GEOM_MULTIPATH: %s now active path in %s\n",
+ sc->sc_active->provider->name, sc->sc_name);
+
+ mtx_unlock(&sc->sc_mtx);
+}
+
+static void
g_multipath_ctl_add(struct gctl_req *req, struct g_class *mp)
{
struct g_multipath_softc *sc;
@@ -1278,6 +1350,8 @@ g_multipath_config(struct gctl_req *req,
gctl_error(req, "Userland and kernel parts are out of sync");
} else if (strcmp(verb, "add") == 0) {
g_multipath_ctl_add(req, mp);
+ } else if (strcmp(verb, "prefer") == 0) {
+ g_multipath_ctl_prefer(req, mp);
} else if (strcmp(verb, "create") == 0) {
g_multipath_ctl_create(req, mp);
} else if (strcmp(verb, "configure") == 0) {
Modified: user/mjacob/sys/kern/kern_clocksource.c
==============================================================================
--- user/mjacob/sys/kern/kern_clocksource.c Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/kern/kern_clocksource.c Fri Aug 3 15:29:19 2012 (r239014)
@@ -205,19 +205,21 @@ handleevents(struct bintime *now, int fa
runs = 0;
while (bintime_cmp(now, &state->nexthard, >=)) {
- bintime_add(&state->nexthard, &hardperiod);
+ bintime_addx(&state->nexthard, hardperiod.frac);
runs++;
}
- if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 &&
- bintime_cmp(&state->nexthard, &nexthard, >))
- nexthard = state->nexthard;
- if (runs && fake < 2) {
- hardclock_cnt(runs, usermode);
- done = 1;
+ if (runs) {
+ if ((timer->et_flags & ET_FLAGS_PERCPU) == 0 &&
+ bintime_cmp(&state->nexthard, &nexthard, >))
+ nexthard = state->nexthard;
+ if (fake < 2) {
+ hardclock_cnt(runs, usermode);
+ done = 1;
+ }
}
runs = 0;
while (bintime_cmp(now, &state->nextstat, >=)) {
- bintime_add(&state->nextstat, &statperiod);
+ bintime_addx(&state->nextstat, statperiod.frac);
runs++;
}
if (runs && fake < 2) {
@@ -227,7 +229,7 @@ handleevents(struct bintime *now, int fa
if (profiling) {
runs = 0;
while (bintime_cmp(now, &state->nextprof, >=)) {
- bintime_add(&state->nextprof, &profperiod);
+ bintime_addx(&state->nextprof, profperiod.frac);
runs++;
}
if (runs && !fake) {
@@ -356,7 +358,7 @@ timercb(struct eventtimer *et, void *arg
next = &nexttick;
if (periodic) {
now = *next; /* Ex-next tick time becomes present time. */
- bintime_add(next, &timerperiod); /* Next tick in 1 period. */
+ bintime_addx(next, timerperiod.frac); /* Next tick in 1 period. */
} else {
binuptime(&now); /* Get present time from hardware. */
next->sec = -1; /* Next tick is not scheduled yet. */
@@ -433,7 +435,7 @@ loadtimer(struct bintime *now, int start
new.sec = 0;
new.frac = timerperiod.frac - tmp;
if (new.frac < tmp) /* Left less then passed. */
- bintime_add(&new, &timerperiod);
+ bintime_addx(&new, timerperiod.frac);
CTR5(KTR_SPARE2, "load p at %d: now %d.%08x first in %d.%08x",
curcpu, now->sec, (unsigned int)(now->frac >> 32),
new.sec, (unsigned int)(new.frac >> 32));
@@ -531,7 +533,7 @@ configtimer(int start)
if (start) {
/* Initialize time machine parameters. */
next = now;
- bintime_add(&next, &timerperiod);
+ bintime_addx(&next, timerperiod.frac);
if (periodic)
nexttick = next;
else
Modified: user/mjacob/sys/netgraph/ng_pptpgre.c
==============================================================================
--- user/mjacob/sys/netgraph/ng_pptpgre.c Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/netgraph/ng_pptpgre.c Fri Aug 3 15:29:19 2012 (r239014)
@@ -562,7 +562,7 @@ ng_pptpgre_xmit(hpriv_p hpriv, item_p it
}
/* Sanity check frame length */
- if (m != NULL && m->m_pkthdr.len > PPTP_MAX_PAYLOAD) {
+ if (m->m_pkthdr.len > PPTP_MAX_PAYLOAD) {
priv->stats.xmitTooBig++;
ERROUT(EMSGSIZE);
}
Modified: user/mjacob/sys/powerpc/powerpc/busdma_machdep.c
==============================================================================
--- user/mjacob/sys/powerpc/powerpc/busdma_machdep.c Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/powerpc/powerpc/busdma_machdep.c Fri Aug 3 15:29:19 2012 (r239014)
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
@@ -130,6 +132,7 @@ struct bus_dmamap {
bus_dmamap_callback_t *callback;
void *callback_arg;
STAILQ_ENTRY(bus_dmamap) links;
+ int contigalloc;
};
static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
@@ -489,6 +492,7 @@ int
bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
bus_dmamap_t *mapp)
{
+ vm_memattr_t attr;
int mflags;
if (flags & BUS_DMA_NOWAIT)
@@ -500,6 +504,12 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
if (flags & BUS_DMA_ZERO)
mflags |= M_ZERO;
+#ifdef NOTYET
+ if (flags & BUS_DMA_NOCACHE)
+ attr = VM_MEMATTR_UNCACHEABLE;
+ else
+#endif
+ attr = VM_MEMATTR_DEFAULT;
/*
* XXX:
@@ -511,7 +521,8 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
*/
if ((dmat->maxsize <= PAGE_SIZE) &&
(dmat->alignment < dmat->maxsize) &&
- dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) {
+ dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem) &&
+ attr == VM_MEMATTR_DEFAULT) {
*vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
} else {
/*
@@ -520,9 +531,10 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
* multi-seg allocations yet though.
* XXX Certain AGP hardware does.
*/
- *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
- 0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
- dmat->boundary);
+ *vaddr = (void *)kmem_alloc_contig(kernel_map, dmat->maxsize,
+ mflags, 0ul, dmat->lowaddr, dmat->alignment ?
+ dmat->alignment : 1ul, dmat->boundary, attr);
+ (*mapp)->contigalloc = 1;
}
if (*vaddr == NULL) {
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
@@ -531,11 +543,6 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
} else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
printf("bus_dmamem_alloc failed to align memory properly.\n");
}
-#ifdef NOTYET
- if (flags & BUS_DMA_NOCACHE)
- pmap_change_attr((vm_offset_t)*vaddr, dmat->maxsize,
- VM_MEMATTR_UNCACHEABLE);
-#endif
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->flags, 0);
return (0);
@@ -548,18 +555,12 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
void
bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
{
- bus_dmamap_destroy(dmat, map);
-#ifdef NOTYET
- pmap_change_attr((vm_offset_t)vaddr, dmat->maxsize, VM_MEMATTR_DEFAULT);
-#endif
- if ((dmat->maxsize <= PAGE_SIZE) &&
- (dmat->alignment < dmat->maxsize) &&
- dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem))
+ if (!map->contigalloc)
free(vaddr, M_DEVBUF);
- else {
- contigfree(vaddr, dmat->maxsize, M_DEVBUF);
- }
+ else
+ kmem_free(kernel_map, (vm_offset_t)vaddr, dmat->maxsize);
+ bus_dmamap_destroy(dmat, map);
CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags);
}
Modified: user/mjacob/sys/x86/x86/busdma_machdep.c
==============================================================================
--- user/mjacob/sys/x86/x86/busdma_machdep.c Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/x86/x86/busdma_machdep.c Fri Aug 3 15:29:19 2012 (r239014)
@@ -42,6 +42,8 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
@@ -131,7 +133,7 @@ struct bus_dmamap {
static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist;
-static struct bus_dmamap nobounce_dmamap;
+static struct bus_dmamap nobounce_dmamap, contig_dmamap;
static void init_bounce_pages(void *dummy);
static int alloc_bounce_zone(bus_dma_tag_t dmat);
@@ -465,7 +467,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, in
int
bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
{
- if (map != NULL && map != &nobounce_dmamap) {
+ if (map != NULL && map != &nobounce_dmamap && map != &contig_dmamap) {
if (STAILQ_FIRST(&map->bpages) != NULL) {
CTR3(KTR_BUSDMA, "%s: tag %p error %d",
__func__, dmat, EBUSY);
@@ -490,6 +492,7 @@ int
bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
bus_dmamap_t *mapp)
{
+ vm_memattr_t attr;
int mflags;
if (flags & BUS_DMA_NOWAIT)
@@ -512,6 +515,10 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
}
if (flags & BUS_DMA_ZERO)
mflags |= M_ZERO;
+ if (flags & BUS_DMA_NOCACHE)
+ attr = VM_MEMATTR_UNCACHEABLE;
+ else
+ attr = VM_MEMATTR_DEFAULT;
/*
* XXX:
@@ -523,7 +530,8 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
*/
if ((dmat->maxsize <= PAGE_SIZE) &&
(dmat->alignment < dmat->maxsize) &&
- dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) {
+ dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem) &&
+ attr == VM_MEMATTR_DEFAULT) {
*vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
} else {
/*
@@ -532,9 +540,10 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
* multi-seg allocations yet though.
* XXX Certain AGP hardware does.
*/
- *vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
- 0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
- dmat->boundary);
+ *vaddr = (void *)kmem_alloc_contig(kernel_map, dmat->maxsize,
+ mflags, 0ul, dmat->lowaddr, dmat->alignment ?
+ dmat->alignment : 1ul, dmat->boundary, attr);
+ *mapp = &contig_dmamap;
}
if (*vaddr == NULL) {
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
@@ -543,9 +552,6 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi
} else if (vtophys(*vaddr) & (dmat->alignment - 1)) {
printf("bus_dmamem_alloc failed to align memory properly.\n");
}
- if (flags & BUS_DMA_NOCACHE)
- pmap_change_attr((vm_offset_t)*vaddr, dmat->maxsize,
- PAT_UNCACHEABLE);
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->flags, 0);
return (0);
@@ -560,18 +566,15 @@ bus_dmamem_free(bus_dma_tag_t dmat, void
{
/*
* dmamem does not need to be bounced, so the map should be
- * NULL
+ * NULL if malloc() was used and contig_dmamap if
+ * contigmalloc() was used.
*/
- if (map != NULL)
+ if (!(map == NULL || map == &contig_dmamap))
panic("bus_dmamem_free: Invalid map freed\n");
- pmap_change_attr((vm_offset_t)vaddr, dmat->maxsize, PAT_WRITE_BACK);
- if ((dmat->maxsize <= PAGE_SIZE) &&
- (dmat->alignment < dmat->maxsize) &&
- dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem))
+ if (map == NULL)
free(vaddr, M_DEVBUF);
- else {
- contigfree(vaddr, dmat->maxsize, M_DEVBUF);
- }
+ else
+ kmem_free(kernel_map, (vm_offset_t)vaddr, dmat->maxsize);
CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, dmat->flags);
}
@@ -662,7 +665,7 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
vm_offset_t vaddr;
int seg, error;
- if (map == NULL)
+ if (map == NULL || map == &contig_dmamap)
map = &nobounce_dmamap;
if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
@@ -1139,7 +1142,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
struct bounce_page *bpage;
KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag"));
- KASSERT(map != NULL && map != &nobounce_dmamap,
+ KASSERT(map != NULL && map != &nobounce_dmamap && map != &contig_dmamap,
("add_bounce_page: bad map %p", map));
bz = dmat->bounce_zone;
Modified: user/mjacob/sys/x86/x86/local_apic.c
==============================================================================
--- user/mjacob/sys/x86/x86/local_apic.c Fri Aug 3 15:19:59 2012 (r239013)
+++ user/mjacob/sys/x86/x86/local_apic.c Fri Aug 3 15:29:19 2012 (r239014)
@@ -119,6 +119,7 @@ struct lapic {
u_long *la_timer_count;
u_long la_timer_period;
u_int la_timer_mode;
+ uint32_t lvt_timer_cache;
/* Include IDT_SYSCALL to make indexing easier. */
int la_ioint_irqs[APIC_NUM_IOINTS + 1];
} static lapics[MAX_APIC_ID + 1];
@@ -160,9 +161,11 @@ static struct eventtimer lapic_et;
static void lapic_enable(void);
static void lapic_resume(struct pic *pic);
-static void lapic_timer_oneshot(u_int count, int enable_int);
-static void lapic_timer_periodic(u_int count, int enable_int);
-static void lapic_timer_stop(void);
+static void lapic_timer_oneshot(struct lapic *,
+ u_int count, int enable_int);
+static void lapic_timer_periodic(struct lapic *,
+ u_int count, int enable_int);
+static void lapic_timer_stop(struct lapic *);
static void lapic_timer_set_divisor(u_int divisor);
static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value);
static int lapic_et_start(struct eventtimer *et,
@@ -370,7 +373,8 @@ lapic_setup(int boot)
lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint);
/* Program timer LVT and setup handler. */
- lapic->lvt_timer = lvt_mode(la, LVT_TIMER, lapic->lvt_timer);
+ la->lvt_timer_cache = lapic->lvt_timer =
+ lvt_mode(la, LVT_TIMER, lapic->lvt_timer);
if (boot) {
snprintf(buf, sizeof(buf), "cpu%d:timer", PCPU_GET(cpuid));
intrcnt_add(buf, &la->la_timer_count);
@@ -382,9 +386,9 @@ lapic_setup(int boot)
lapic_id()));
lapic_timer_set_divisor(lapic_timer_divisor);
if (la->la_timer_mode == 1)
- lapic_timer_periodic(la->la_timer_period, 1);
+ lapic_timer_periodic(la, la->la_timer_period, 1);
else
- lapic_timer_oneshot(la->la_timer_period, 1);
+ lapic_timer_oneshot(la, la->la_timer_period, 1);
}
/* Program error LVT and clear any existing errors. */
@@ -489,13 +493,14 @@ lapic_et_start(struct eventtimer *et,
struct lapic *la;
u_long value;
+ la = &lapics[PCPU_GET(apic_id)];
if (et->et_frequency == 0) {
/* Start off with a divisor of 2 (power on reset default). */
lapic_timer_divisor = 2;
/* Try to calibrate the local APIC timer. */
do {
lapic_timer_set_divisor(lapic_timer_divisor);
- lapic_timer_oneshot(APIC_TIMER_MAX_COUNT, 0);
+ lapic_timer_oneshot(la, APIC_TIMER_MAX_COUNT, 0);
DELAY(1000000);
value = APIC_TIMER_MAX_COUNT - lapic->ccr_timer;
if (value != APIC_TIMER_MAX_COUNT)
@@ -515,22 +520,22 @@ lapic_et_start(struct eventtimer *et,
et->et_max_period.frac =
((0xfffffffeLLU << 32) / et->et_frequency) << 32;
}
- lapic_timer_set_divisor(lapic_timer_divisor);
- la = &lapics[lapic_id()];
+ if (la->la_timer_mode == 0)
+ lapic_timer_set_divisor(lapic_timer_divisor);
if (period != NULL) {
la->la_timer_mode = 1;
la->la_timer_period =
(et->et_frequency * (period->frac >> 32)) >> 32;
if (period->sec != 0)
la->la_timer_period += et->et_frequency * period->sec;
- lapic_timer_periodic(la->la_timer_period, 1);
+ lapic_timer_periodic(la, la->la_timer_period, 1);
} else {
la->la_timer_mode = 2;
la->la_timer_period =
(et->et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
la->la_timer_period += et->et_frequency * first->sec;
- lapic_timer_oneshot(la->la_timer_period, 1);
+ lapic_timer_oneshot(la, la->la_timer_period, 1);
}
return (0);
}
@@ -538,10 +543,10 @@ lapic_et_start(struct eventtimer *et,
static int
lapic_et_stop(struct eventtimer *et)
{
- struct lapic *la = &lapics[lapic_id()];
+ struct lapic *la = &lapics[PCPU_GET(apic_id)];
la->la_timer_mode = 0;
- lapic_timer_stop();
+ lapic_timer_stop(la);
return (0);
}
@@ -835,11 +840,11 @@ lapic_timer_set_divisor(u_int divisor)
}
static void
-lapic_timer_oneshot(u_int count, int enable_int)
+lapic_timer_oneshot(struct lapic *la, u_int count, int enable_int)
{
u_int32_t value;
- value = lapic->lvt_timer;
+ value = la->lvt_timer_cache;
value &= ~APIC_LVTT_TM;
value |= APIC_LVTT_TM_ONE_SHOT;
if (enable_int)
@@ -849,11 +854,11 @@ lapic_timer_oneshot(u_int count, int ena
}
static void
-lapic_timer_periodic(u_int count, int enable_int)
+lapic_timer_periodic(struct lapic *la, u_int count, int enable_int)
{
u_int32_t value;
- value = lapic->lvt_timer;
+ value = la->lvt_timer_cache;
value &= ~APIC_LVTT_TM;
value |= APIC_LVTT_TM_PERIODIC;
if (enable_int)
@@ -863,11 +868,11 @@ lapic_timer_periodic(u_int count, int en
}
static void
-lapic_timer_stop(void)
+lapic_timer_stop(struct lapic *la)
{
u_int32_t value;
- value = lapic->lvt_timer;
+ value = la->lvt_timer_cache;
value &= ~APIC_LVTT_TM;
value |= APIC_LVT_M;
lapic->lvt_timer = value;
More information about the svn-src-user
mailing list