smist.c (145287) | smist.c (170874) |
---|---|
1/*- 2 * Copyright (c) 2005 Bruno Ducrot 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 22 unchanged lines hidden (view full) --- 31 * Hiroshi Miura (function 0 of the GSI). 32 * 33 * Finally, the int 15h call interface was (partially) documented by Intel. 34 * 35 * Many thanks to Jon Noack for testing and debugging this driver. 36 */ 37 38#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2005 Bruno Ducrot 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 22 unchanged lines hidden (view full) --- 31 * Hiroshi Miura (function 0 of the GSI). 32 * 33 * Finally, the int 15h call interface was (partially) documented by Intel. 34 * 35 * Many thanks to Jon Noack for testing and debugging this driver. 36 */ 37 38#include <sys/cdefs.h> |
39__FBSDID("$FreeBSD: head/sys/i386/cpufreq/smist.c 145287 2005-04-19 16:38:24Z njl $"); | 39__FBSDID("$FreeBSD: head/sys/i386/cpufreq/smist.c 170874 2007-06-17 07:18:23Z njl $"); |
40 41#include <sys/param.h> 42#include <sys/bus.h> 43#include <sys/cpu.h> 44#include <sys/kernel.h> 45#include <sys/module.h> 46#include <sys/systm.h> 47 | 40 41#include <sys/param.h> 42#include <sys/bus.h> 43#include <sys/cpu.h> 44#include <sys/kernel.h> 45#include <sys/module.h> 46#include <sys/systm.h> 47 |
48#include <machine/bus.h> |
|
48#include <machine/md_var.h> 49#include <machine/vm86.h> 50 51#include <dev/pci/pcivar.h> 52#include <dev/pci/pcireg.h> 53 54#include <vm/vm.h> 55#include <vm/pmap.h> --- 10 unchanged lines hidden (view full) --- 66 device_t dev; 67 int smi_cmd; 68 int smi_data; 69 int command; 70 int flags; 71 struct cf_setting sets[2]; /* Only two settings. */ 72}; 73 | 49#include <machine/md_var.h> 50#include <machine/vm86.h> 51 52#include <dev/pci/pcivar.h> 53#include <dev/pci/pcireg.h> 54 55#include <vm/vm.h> 56#include <vm/pmap.h> --- 10 unchanged lines hidden (view full) --- 67 device_t dev; 68 int smi_cmd; 69 int smi_data; 70 int command; 71 int flags; 72 struct cf_setting sets[2]; /* Only two settings. */ 73}; 74 |
75static char smist_magic[] = "Copyright (c) 1999 Intel Corporation"; 76 |
|
74static void smist_identify(driver_t *driver, device_t parent); 75static int smist_probe(device_t dev); 76static int smist_attach(device_t dev); 77static int smist_detach(device_t dev); 78static int smist_settings(device_t dev, struct cf_setting *sets, 79 int *count); 80static int smist_set(device_t dev, const struct cf_setting *set); 81static int smist_get(device_t dev, struct cf_setting *set); --- 60 unchanged lines hidden (view full) --- 142 *command = -1; 143 *smi_data = -1; 144 *flags = -1; 145 } 146 147 return (0); 148} 149 | 77static void smist_identify(driver_t *driver, device_t parent); 78static int smist_probe(device_t dev); 79static int smist_attach(device_t dev); 80static int smist_detach(device_t dev); 81static int smist_settings(device_t dev, struct cf_setting *sets, 82 int *count); 83static int smist_set(device_t dev, const struct cf_setting *set); 84static int smist_get(device_t dev, struct cf_setting *set); --- 60 unchanged lines hidden (view full) --- 145 *command = -1; 146 *smi_data = -1; 147 *flags = -1; 148 } 149 150 return (0); 151} 152 |
150static int 151set_ownership(device_t dev) | 153/* Temporary structure to hold mapped page and status. */ 154struct set_ownership_data { 155 int smi_cmd; 156 int command; 157 int result; 158 void *buf; 159}; 160 161/* Perform actual SMI call to enable SpeedStep. */ 162static void 163set_ownership_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) |
152{ | 164{ |
153 int result; 154 struct smist_softc *sc; 155 vm_paddr_t pmagic; 156 static char magic[] = "Copyright (c) 1999 Intel Corporation"; | 165 struct set_ownership_data *data; |
157 | 166 |
158 sc = device_get_softc(dev); 159 if (!sc) 160 return (ENXIO); | 167 data = arg; 168 if (error) { 169 data->result = error; 170 return; 171 } |
161 | 172 |
162 pmagic = vtophys(magic); 163 | 173 /* Copy in the magic string and send it by writing to the SMI port. */ 174 strlcpy(data->buf, smist_magic, PAGE_SIZE); |
164 __asm __volatile( 165 "movl $-1, %%edi\n\t" 166 "out %%al, (%%dx)\n" | 175 __asm __volatile( 176 "movl $-1, %%edi\n\t" 177 "out %%al, (%%dx)\n" |
167 : "=D" (result) 168 : "a" (sc->command), | 178 : "=D" (data->result) 179 : "a" (data->command), |
169 "b" (0), 170 "c" (0), | 180 "b" (0), 181 "c" (0), |
171 "d" (sc->smi_cmd), 172 "S" (pmagic) | 182 "d" (data->smi_cmd), 183 "S" ((uint32_t)segs[0].ds_addr) |
173 ); | 184 ); |
185} |
|
174 | 186 |
175 DPRINT(dev, "taking ownership over BIOS return %d\n", result); | 187static int 188set_ownership(device_t dev) 189{ 190 struct smist_softc *sc; 191 struct set_ownership_data cb_data; 192 bus_dma_tag_t tag; 193 bus_dmamap_t map; |
176 | 194 |
177 return (result ? ENXIO : 0); | 195 /* 196 * Specify the region to store the magic string. Since its address is 197 * passed to the BIOS in a 32-bit register, we have to make sure it is 198 * located in a physical page below 4 GB (i.e., for PAE.) 199 */ 200 sc = device_get_softc(dev); 201 if (bus_dma_tag_create(/*parent*/ NULL, 202 /*alignment*/ PAGE_SIZE, /*no boundary*/ 0, 203 /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT, /*highaddr*/ BUS_SPACE_MAXADDR, 204 NULL, NULL, /*maxsize*/ PAGE_SIZE, /*segments*/ 1, 205 /*maxsegsize*/ PAGE_SIZE, 0, busdma_lock_mutex, &Giant, 206 &tag) != 0) { 207 device_printf(dev, "can't create mem tag\n"); 208 return (ENXIO); 209 } 210 if (bus_dmamem_alloc(tag, &cb_data.buf, BUS_DMA_NOWAIT, &map) != 0) { 211 bus_dma_tag_destroy(tag); 212 device_printf(dev, "can't alloc mapped mem\n"); 213 return (ENXIO); 214 } 215 216 /* Load the physical page map and take ownership in the callback. */ 217 cb_data.smi_cmd = sc->smi_cmd; 218 cb_data.command = sc->command; 219 if (bus_dmamap_load(tag, map, cb_data.buf, PAGE_SIZE, set_ownership_cb, 220 &cb_data, BUS_DMA_NOWAIT) != 0) { 221 bus_dmamem_free(tag, cb_data.buf, map); 222 bus_dma_tag_destroy(tag); 223 device_printf(dev, "can't load mem\n"); 224 return (ENXIO); 225 }; 226 DPRINT(dev, "taking ownership over BIOS return %d\n", cb_data.result); 227 bus_dmamap_unload(tag, map); 228 bus_dmamem_free(tag, cb_data.buf, map); 229 bus_dma_tag_destroy(tag); 230 return (cb_data.result ? ENXIO : 0); |
178} 179 180static int 181getset_state(struct smist_softc *sc, int *state, int function) 182{ 183 int new_state; 184 int result; 185 int eax; --- 275 unchanged lines hidden --- | 231} 232 233static int 234getset_state(struct smist_softc *sc, int *state, int function) 235{ 236 int new_state; 237 int result; 238 int eax; --- 275 unchanged lines hidden --- |