subr_hal.c (139743) | subr_hal.c (140751) |
---|---|
1/*- 2 * Copyright (c) 2003 3 * Bill Paul <wpaul@windriver.com>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 3 * Bill Paul <wpaul@windriver.com>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/compat/ndis/subr_hal.c 139743 2005-01-05 22:34:37Z imp $"); | 34__FBSDID("$FreeBSD: head/sys/compat/ndis/subr_hal.c 140751 2005-01-24 18:18:12Z wpaul $"); |
35 36#include <sys/param.h> 37#include <sys/types.h> 38#include <sys/errno.h> 39 40#include <sys/callout.h> 41#include <sys/kernel.h> 42#include <sys/lock.h> --- 9 unchanged lines hidden (view full) --- 52 53#include <sys/bus.h> 54#include <sys/rman.h> 55 56#include <compat/ndis/pe_var.h> 57#include <compat/ndis/ntoskrnl_var.h> 58#include <compat/ndis/hal_var.h> 59 | 35 36#include <sys/param.h> 37#include <sys/types.h> 38#include <sys/errno.h> 39 40#include <sys/callout.h> 41#include <sys/kernel.h> 42#include <sys/lock.h> --- 9 unchanged lines hidden (view full) --- 52 53#include <sys/bus.h> 54#include <sys/rman.h> 55 56#include <compat/ndis/pe_var.h> 57#include <compat/ndis/ntoskrnl_var.h> 58#include <compat/ndis/hal_var.h> 59 |
60#define FUNC void(*)(void) 61 62__stdcall static void hal_stall_exec_cpu(uint32_t); 63__stdcall static void hal_writeport_buf_ulong(uint32_t *, | 60__stdcall static void KeStallExecutionProcessor(uint32_t); 61__stdcall static void WRITE_PORT_BUFFER_ULONG(uint32_t *, |
64 uint32_t *, uint32_t); | 62 uint32_t *, uint32_t); |
65__stdcall static void hal_writeport_buf_ushort(uint16_t *, | 63__stdcall static void WRITE_PORT_BUFFER_USHORT(uint16_t *, |
66 uint16_t *, uint32_t); | 64 uint16_t *, uint32_t); |
67__stdcall static void hal_writeport_buf_uchar(uint8_t *, | 65__stdcall static void WRITE_PORT_BUFFER_UCHAR(uint8_t *, |
68 uint8_t *, uint32_t); | 66 uint8_t *, uint32_t); |
69__stdcall static void hal_writeport_ulong(uint32_t *, uint32_t); 70__stdcall static void hal_writeport_ushort(uint16_t *, uint16_t); 71__stdcall static void hal_writeport_uchar(uint8_t *, uint8_t); 72__stdcall static uint32_t hal_readport_ulong(uint32_t *); 73__stdcall static uint16_t hal_readport_ushort(uint16_t *); 74__stdcall static uint8_t hal_readport_uchar(uint8_t *); 75__stdcall static void hal_readport_buf_ulong(uint32_t *, | 67__stdcall static void WRITE_PORT_ULONG(uint32_t *, uint32_t); 68__stdcall static void WRITE_PORT_USHORT(uint16_t *, uint16_t); 69__stdcall static void WRITE_PORT_UCHAR(uint8_t *, uint8_t); 70__stdcall static uint32_t READ_PORT_ULONG(uint32_t *); 71__stdcall static uint16_t READ_PORT_USHORT(uint16_t *); 72__stdcall static uint8_t READ_PORT_UCHAR(uint8_t *); 73__stdcall static void READ_PORT_BUFFER_ULONG(uint32_t *, |
76 uint32_t *, uint32_t); | 74 uint32_t *, uint32_t); |
77__stdcall static void hal_readport_buf_ushort(uint16_t *, | 75__stdcall static void READ_PORT_BUFFER_USHORT(uint16_t *, |
78 uint16_t *, uint32_t); | 76 uint16_t *, uint32_t); |
79__stdcall static void hal_readport_buf_uchar(uint8_t *, | 77__stdcall static void READ_PORT_BUFFER_UCHAR(uint8_t *, |
80 uint8_t *, uint32_t); | 78 uint8_t *, uint32_t); |
81__stdcall static uint64_t hal_perfcount(uint64_t *); | 79__stdcall static uint64_t KeQueryPerformanceCounter(uint64_t *); |
82__stdcall static void dummy (void); 83 84extern struct mtx_pool *ndis_mtxpool; 85 86__stdcall static void | 80__stdcall static void dummy (void); 81 82extern struct mtx_pool *ndis_mtxpool; 83 84__stdcall static void |
87hal_stall_exec_cpu(usecs) | 85KeStallExecutionProcessor(usecs) |
88 uint32_t usecs; 89{ 90 DELAY(usecs); 91 return; 92} 93 94__stdcall static void | 86 uint32_t usecs; 87{ 88 DELAY(usecs); 89 return; 90} 91 92__stdcall static void |
95hal_writeport_ulong(port, val) | 93WRITE_PORT_ULONG(port, val) |
96 uint32_t *port; 97 uint32_t val; 98{ 99 bus_space_write_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val); 100 return; 101} 102 103__stdcall static void | 94 uint32_t *port; 95 uint32_t val; 96{ 97 bus_space_write_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val); 98 return; 99} 100 101__stdcall static void |
104hal_writeport_ushort(port, val) | 102WRITE_PORT_USHORT(port, val) |
105 uint16_t *port; 106 uint16_t val; 107{ 108 bus_space_write_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val); 109 return; 110} 111 112__stdcall static void | 103 uint16_t *port; 104 uint16_t val; 105{ 106 bus_space_write_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val); 107 return; 108} 109 110__stdcall static void |
113hal_writeport_uchar(port, val) | 111WRITE_PORT_UCHAR(port, val) |
114 uint8_t *port; 115 uint8_t val; 116{ 117 bus_space_write_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val); 118 return; 119} 120 121__stdcall static void | 112 uint8_t *port; 113 uint8_t val; 114{ 115 bus_space_write_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val); 116 return; 117} 118 119__stdcall static void |
122hal_writeport_buf_ulong(port, val, cnt) | 120WRITE_PORT_BUFFER_ULONG(port, val, cnt) |
123 uint32_t *port; 124 uint32_t *val; 125 uint32_t cnt; 126{ 127 bus_space_write_multi_4(NDIS_BUS_SPACE_IO, 0x0, 128 (bus_size_t)port, val, cnt); 129 return; 130} 131 132__stdcall static void | 121 uint32_t *port; 122 uint32_t *val; 123 uint32_t cnt; 124{ 125 bus_space_write_multi_4(NDIS_BUS_SPACE_IO, 0x0, 126 (bus_size_t)port, val, cnt); 127 return; 128} 129 130__stdcall static void |
133hal_writeport_buf_ushort(port, val, cnt) | 131WRITE_PORT_BUFFER_USHORT(port, val, cnt) |
134 uint16_t *port; 135 uint16_t *val; 136 uint32_t cnt; 137{ 138 bus_space_write_multi_2(NDIS_BUS_SPACE_IO, 0x0, 139 (bus_size_t)port, val, cnt); 140 return; 141} 142 143__stdcall static void | 132 uint16_t *port; 133 uint16_t *val; 134 uint32_t cnt; 135{ 136 bus_space_write_multi_2(NDIS_BUS_SPACE_IO, 0x0, 137 (bus_size_t)port, val, cnt); 138 return; 139} 140 141__stdcall static void |
144hal_writeport_buf_uchar(port, val, cnt) | 142WRITE_PORT_BUFFER_UCHAR(port, val, cnt) |
145 uint8_t *port; 146 uint8_t *val; 147 uint32_t cnt; 148{ 149 bus_space_write_multi_1(NDIS_BUS_SPACE_IO, 0x0, 150 (bus_size_t)port, val, cnt); 151 return; 152} 153 154__stdcall static uint16_t | 143 uint8_t *port; 144 uint8_t *val; 145 uint32_t cnt; 146{ 147 bus_space_write_multi_1(NDIS_BUS_SPACE_IO, 0x0, 148 (bus_size_t)port, val, cnt); 149 return; 150} 151 152__stdcall static uint16_t |
155hal_readport_ushort(port) | 153READ_PORT_USHORT(port) |
156 uint16_t *port; 157{ 158 return(bus_space_read_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port)); 159} 160 161__stdcall static uint32_t | 154 uint16_t *port; 155{ 156 return(bus_space_read_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port)); 157} 158 159__stdcall static uint32_t |
162hal_readport_ulong(port) | 160READ_PORT_ULONG(port) |
163 uint32_t *port; 164{ 165 return(bus_space_read_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port)); 166} 167 168__stdcall static uint8_t | 161 uint32_t *port; 162{ 163 return(bus_space_read_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port)); 164} 165 166__stdcall static uint8_t |
169hal_readport_uchar(port) | 167READ_PORT_UCHAR(port) |
170 uint8_t *port; 171{ 172 return(bus_space_read_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port)); 173} 174 175__stdcall static void | 168 uint8_t *port; 169{ 170 return(bus_space_read_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port)); 171} 172 173__stdcall static void |
176hal_readport_buf_ulong(port, val, cnt) | 174READ_PORT_BUFFER_ULONG(port, val, cnt) |
177 uint32_t *port; 178 uint32_t *val; 179 uint32_t cnt; 180{ 181 bus_space_read_multi_4(NDIS_BUS_SPACE_IO, 0x0, 182 (bus_size_t)port, val, cnt); 183 return; 184} 185 186__stdcall static void | 175 uint32_t *port; 176 uint32_t *val; 177 uint32_t cnt; 178{ 179 bus_space_read_multi_4(NDIS_BUS_SPACE_IO, 0x0, 180 (bus_size_t)port, val, cnt); 181 return; 182} 183 184__stdcall static void |
187hal_readport_buf_ushort(port, val, cnt) | 185READ_PORT_BUFFER_USHORT(port, val, cnt) |
188 uint16_t *port; 189 uint16_t *val; 190 uint32_t cnt; 191{ 192 bus_space_read_multi_2(NDIS_BUS_SPACE_IO, 0x0, 193 (bus_size_t)port, val, cnt); 194 return; 195} 196 197__stdcall static void | 186 uint16_t *port; 187 uint16_t *val; 188 uint32_t cnt; 189{ 190 bus_space_read_multi_2(NDIS_BUS_SPACE_IO, 0x0, 191 (bus_size_t)port, val, cnt); 192 return; 193} 194 195__stdcall static void |
198hal_readport_buf_uchar(port, val, cnt) | 196READ_PORT_BUFFER_UCHAR(port, val, cnt) |
199 uint8_t *port; 200 uint8_t *val; 201 uint32_t cnt; 202{ 203 bus_space_read_multi_1(NDIS_BUS_SPACE_IO, 0x0, 204 (bus_size_t)port, val, cnt); 205 return; 206} --- 41 unchanged lines hidden (view full) --- 248 * 249 * According to the Microsoft documentation, any thread that calls 250 * KeAcquireSpinLock() must be running at IRQL <= DISPATCH_LEVEL. If 251 * we detect someone trying to acquire a spinlock from DEVICE_LEVEL 252 * or HIGH_LEVEL, we panic. 253 */ 254 255__fastcall uint8_t | 197 uint8_t *port; 198 uint8_t *val; 199 uint32_t cnt; 200{ 201 bus_space_read_multi_1(NDIS_BUS_SPACE_IO, 0x0, 202 (bus_size_t)port, val, cnt); 203 return; 204} --- 41 unchanged lines hidden (view full) --- 246 * 247 * According to the Microsoft documentation, any thread that calls 248 * KeAcquireSpinLock() must be running at IRQL <= DISPATCH_LEVEL. If 249 * we detect someone trying to acquire a spinlock from DEVICE_LEVEL 250 * or HIGH_LEVEL, we panic. 251 */ 252 253__fastcall uint8_t |
256hal_lock(REGARGS1(kspin_lock *lock)) | 254KfAcquireSpinLock(REGARGS1(kspin_lock *lock)) |
257{ 258 uint8_t oldirql; 259 260 /* I am so going to hell for this. */ | 255{ 256 uint8_t oldirql; 257 258 /* I am so going to hell for this. */ |
261 if (hal_irql() > DISPATCH_LEVEL) | 259 if (KeGetCurrentIrql() > DISPATCH_LEVEL) |
262 panic("IRQL_NOT_LESS_THAN_OR_EQUAL"); 263 | 260 panic("IRQL_NOT_LESS_THAN_OR_EQUAL"); 261 |
264 oldirql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL); 265 FASTCALL1(ntoskrnl_lock_dpc, lock); | 262 oldirql = FASTCALL1(KfRaiseIrql, DISPATCH_LEVEL); 263 FASTCALL1(KefAcquireSpinLockAtDpcLevel, lock); |
266 267 return(oldirql); 268} 269 270__fastcall void | 264 265 return(oldirql); 266} 267 268__fastcall void |
271hal_unlock(REGARGS2(kspin_lock *lock, uint8_t newirql)) | 269KfReleaseSpinLock(REGARGS2(kspin_lock *lock, uint8_t newirql)) |
272{ | 270{ |
273 FASTCALL1(ntoskrnl_unlock_dpc, lock); 274 FASTCALL1(hal_lower_irql, newirql); | 271 FASTCALL1(KefReleaseSpinLockFromDpcLevel, lock); 272 FASTCALL1(KfLowerIrql, newirql); |
275 276 return; 277} 278 279__stdcall uint8_t | 273 274 return; 275} 276 277__stdcall uint8_t |
280hal_irql(void) | 278KeGetCurrentIrql(void) |
281{ 282 if (AT_DISPATCH_LEVEL(curthread)) 283 return(DISPATCH_LEVEL); 284 return(PASSIVE_LEVEL); 285} 286 287__stdcall static uint64_t | 279{ 280 if (AT_DISPATCH_LEVEL(curthread)) 281 return(DISPATCH_LEVEL); 282 return(PASSIVE_LEVEL); 283} 284 285__stdcall static uint64_t |
288hal_perfcount(freq) | 286KeQueryPerformanceCounter(freq) |
289 uint64_t *freq; 290{ 291 if (freq != NULL) 292 *freq = hz; 293 294 return((uint64_t)ticks); 295} 296 297__fastcall uint8_t | 287 uint64_t *freq; 288{ 289 if (freq != NULL) 290 *freq = hz; 291 292 return((uint64_t)ticks); 293} 294 295__fastcall uint8_t |
298hal_raise_irql(REGARGS1(uint8_t irql)) | 296KfRaiseIrql(REGARGS1(uint8_t irql)) |
299{ 300 uint8_t oldirql; 301 | 297{ 298 uint8_t oldirql; 299 |
302 if (irql < hal_irql()) | 300 if (irql < KeGetCurrentIrql()) |
303 panic("IRQL_NOT_LESS_THAN"); 304 | 301 panic("IRQL_NOT_LESS_THAN"); 302 |
305 if (hal_irql() == DISPATCH_LEVEL) | 303 if (KeGetCurrentIrql() == DISPATCH_LEVEL) |
306 return(DISPATCH_LEVEL); 307 308 mtx_lock_spin(&sched_lock); 309 oldirql = curthread->td_base_pri; 310 sched_prio(curthread, PI_REALTIME); 311 mtx_unlock_spin(&sched_lock); 312 313 return(oldirql); 314} 315 316__fastcall void | 304 return(DISPATCH_LEVEL); 305 306 mtx_lock_spin(&sched_lock); 307 oldirql = curthread->td_base_pri; 308 sched_prio(curthread, PI_REALTIME); 309 mtx_unlock_spin(&sched_lock); 310 311 return(oldirql); 312} 313 314__fastcall void |
317hal_lower_irql(REGARGS1(uint8_t oldirql)) | 315KfLowerIrql(REGARGS1(uint8_t oldirql)) |
318{ 319 if (oldirql == DISPATCH_LEVEL) 320 return; 321 | 316{ 317 if (oldirql == DISPATCH_LEVEL) 318 return; 319 |
322 if (hal_irql() != DISPATCH_LEVEL) | 320 if (KeGetCurrentIrql() != DISPATCH_LEVEL) |
323 panic("IRQL_NOT_GREATER_THAN"); 324 325 mtx_lock_spin(&sched_lock); 326 sched_prio(curthread, oldirql); 327 mtx_unlock_spin(&sched_lock); 328 329 return; 330} 331 332__stdcall 333static void dummy() 334{ 335 printf ("hal dummy called...\n"); 336 return; 337} 338 339image_patch_table hal_functbl[] = { | 321 panic("IRQL_NOT_GREATER_THAN"); 322 323 mtx_lock_spin(&sched_lock); 324 sched_prio(curthread, oldirql); 325 mtx_unlock_spin(&sched_lock); 326 327 return; 328} 329 330__stdcall 331static void dummy() 332{ 333 printf ("hal dummy called...\n"); 334 return; 335} 336 337image_patch_table hal_functbl[] = { |
340 { "KeStallExecutionProcessor", (FUNC)hal_stall_exec_cpu }, 341 { "WRITE_PORT_ULONG", (FUNC)hal_writeport_ulong }, 342 { "WRITE_PORT_USHORT", (FUNC)hal_writeport_ushort }, 343 { "WRITE_PORT_UCHAR", (FUNC)hal_writeport_uchar }, 344 { "WRITE_PORT_BUFFER_ULONG", (FUNC)hal_writeport_buf_ulong }, 345 { "WRITE_PORT_BUFFER_USHORT", (FUNC)hal_writeport_buf_ushort }, 346 { "WRITE_PORT_BUFFER_UCHAR", (FUNC)hal_writeport_buf_uchar }, 347 { "READ_PORT_ULONG", (FUNC)hal_readport_ulong }, 348 { "READ_PORT_USHORT", (FUNC)hal_readport_ushort }, 349 { "READ_PORT_UCHAR", (FUNC)hal_readport_uchar }, 350 { "READ_PORT_BUFFER_ULONG", (FUNC)hal_readport_buf_ulong }, 351 { "READ_PORT_BUFFER_USHORT", (FUNC)hal_readport_buf_ushort }, 352 { "READ_PORT_BUFFER_UCHAR", (FUNC)hal_readport_buf_uchar }, 353 { "KfAcquireSpinLock", (FUNC)hal_lock }, 354 { "KfReleaseSpinLock", (FUNC)hal_unlock }, 355 { "KeGetCurrentIrql", (FUNC)hal_irql }, 356 { "KeQueryPerformanceCounter", (FUNC)hal_perfcount }, 357 { "KfLowerIrql", (FUNC)hal_lower_irql }, 358 { "KfRaiseIrql", (FUNC)hal_raise_irql }, | 338 IMPORT_FUNC(KeStallExecutionProcessor), 339 IMPORT_FUNC(WRITE_PORT_ULONG), 340 IMPORT_FUNC(WRITE_PORT_USHORT), 341 IMPORT_FUNC(WRITE_PORT_UCHAR), 342 IMPORT_FUNC(WRITE_PORT_BUFFER_ULONG), 343 IMPORT_FUNC(WRITE_PORT_BUFFER_USHORT), 344 IMPORT_FUNC(WRITE_PORT_BUFFER_UCHAR), 345 IMPORT_FUNC(READ_PORT_ULONG), 346 IMPORT_FUNC(READ_PORT_USHORT), 347 IMPORT_FUNC(READ_PORT_UCHAR), 348 IMPORT_FUNC(READ_PORT_BUFFER_ULONG), 349 IMPORT_FUNC(READ_PORT_BUFFER_USHORT), 350 IMPORT_FUNC(READ_PORT_BUFFER_UCHAR), 351 IMPORT_FUNC(KfAcquireSpinLock), 352 IMPORT_FUNC(KfReleaseSpinLock), 353 IMPORT_FUNC(KeGetCurrentIrql), 354 IMPORT_FUNC(KeQueryPerformanceCounter), 355 IMPORT_FUNC(KfLowerIrql), 356 IMPORT_FUNC(KfRaiseIrql), |
359 360 /* 361 * This last entry is a catch-all for any function we haven't 362 * implemented yet. The PE import list patching routine will 363 * use it for any function that doesn't have an explicit match 364 * in this table. 365 */ 366 367 { NULL, (FUNC)dummy }, 368 369 /* End of list. */ 370 371 { NULL, NULL }, 372}; | 357 358 /* 359 * This last entry is a catch-all for any function we haven't 360 * implemented yet. The PE import list patching routine will 361 * use it for any function that doesn't have an explicit match 362 * in this table. 363 */ 364 365 { NULL, (FUNC)dummy }, 366 367 /* End of list. */ 368 369 { NULL, NULL }, 370}; |