This source file includes following definitions.
- cyrix_read_reg
- cyrix_write_reg
- cpuid
- cpu_startup
- i386_proc0_tss_ldt_init
- i386_init_pcb_tss_ldt
- allocsys
- setup_buffers
- winchip_cpu_setup
- cyrix3_setperf_setup
- cyrix3_cpu_setup
- cyrix6x86_cpu_setup
- natsem6x86_cpu_setup
- intel586_cpu_setup
- amd_family5_setperf_setup
- amd_family5_setup
- amd_family6_setperf_setup
- amd_family6_setup
- intelcore_update_sensor
- intel686_cpusensors_setup
- intel686_setperf_setup
- intel686_common_cpu_setup
- intel686_cpu_setup
- intel686_p4_cpu_setup
- tm86_cpu_setup
- intel686_cpu_name
- cyrix3_cpu_name
- identifycpu
- tm86_cpu_name
- cyrix3_get_bus_clock
- p4_get_bus_clock
- p3_get_bus_clock
- p4_update_cpuspeed
- p3_update_cpuspeed
- pentium_cpuspeed
- ibcs2_sendsig
- aston
- sendsig
- sys_sigreturn
- boot
- dumpconf
- cpu_dump
- reserve_dumppages
- dumpsys
- setregs
- setgate
- unsetgate
- setregion
- setsegment
- fix_f00f
- cpu_init_idt
- cpu_default_ldt
- cpu_alloc_ldt
- cpu_init_ldt
- init386
- cpu_exec_aout_makecmds
- consinit
- kgdb_port_init
- cpu_reset
- cpu_initclocks
- need_resched
- idt_vec_alloc
- idt_vec_set
- idt_vec_free
- cpu_sysctl
- bus_space_map
- _bus_space_map
- bus_space_alloc
- bus_mem_add_mapping
- bus_space_unmap
- _bus_space_unmap
- bus_space_free
- bus_space_subregion
- _bus_dmamap_create
- _bus_dmamap_destroy
- _bus_dmamap_load
- _bus_dmamap_load_mbuf
- _bus_dmamap_load_uio
- _bus_dmamap_load_raw
- _bus_dmamap_unload
- _bus_dmamem_alloc
- _bus_dmamem_free
- _bus_dmamem_map
- _bus_dmamem_unmap
- _bus_dmamem_mmap
- _bus_dmamap_load_buffer
- _bus_dmamem_alloc_range
- splassert_check
- i386_intlock
- i386_intunlock
- i386_softintlock
- i386_softintunlock
- softintr
- splraise
- splx
- spllower
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/signalvar.h>
80 #include <sys/kernel.h>
81 #include <sys/proc.h>
82 #include <sys/user.h>
83 #include <sys/exec.h>
84 #include <sys/buf.h>
85 #include <sys/reboot.h>
86 #include <sys/conf.h>
87 #include <sys/file.h>
88 #include <sys/timeout.h>
89 #include <sys/malloc.h>
90 #include <sys/mbuf.h>
91 #include <sys/msgbuf.h>
92 #include <sys/mount.h>
93 #include <sys/vnode.h>
94 #include <sys/device.h>
95 #include <sys/extent.h>
96 #include <sys/sysctl.h>
97 #include <sys/syscallargs.h>
98 #include <sys/core.h>
99 #include <sys/kcore.h>
100 #include <sys/sensors.h>
101 #ifdef SYSVMSG
102 #include <sys/msg.h>
103 #endif
104
105 #ifdef KGDB
106 #include <sys/kgdb.h>
107 #endif
108
109 #include <dev/cons.h>
110 #include <stand/boot/bootarg.h>
111
112 #include <uvm/uvm_extern.h>
113
114 #define _I386_BUS_DMA_PRIVATE
115 #include <machine/bus.h>
116
117 #include <machine/cpu.h>
118 #include <machine/cpufunc.h>
119 #include <machine/cpuvar.h>
120 #include <machine/gdt.h>
121 #include <machine/pio.h>
122 #include <machine/bus.h>
123 #include <machine/psl.h>
124 #include <machine/reg.h>
125 #include <machine/specialreg.h>
126 #include <machine/biosvar.h>
127
128 #include <dev/rndvar.h>
129 #include <dev/isa/isareg.h>
130 #include <dev/isa/isavar.h>
131 #include <dev/ic/i8042reg.h>
132 #include <dev/ic/mc146818reg.h>
133 #include <i386/isa/isa_machdep.h>
134 #include <i386/isa/nvram.h>
135
136 #include "acpi.h"
137 #if NACPI > 0
138 #include <dev/acpi/acpivar.h>
139 #endif
140
141 #include "apm.h"
142 #if NAPM > 0
143 #include <machine/apmvar.h>
144 #endif
145
146 #ifdef DDB
147 #include <machine/db_machdep.h>
148 #include <ddb/db_access.h>
149 #include <ddb/db_sym.h>
150 #include <ddb/db_extern.h>
151 #endif
152
153 #ifdef VM86
154 #include <machine/vm86.h>
155 #endif
156
157 #include "isa.h"
158 #include "isadma.h"
159 #include "npx.h"
160 #if NNPX > 0
161 extern struct proc *npxproc;
162 #endif
163
164 #include "bios.h"
165 #include "com.h"
166 #include "pccom.h"
167
168 #if NPCCOM > 0
169 #include <sys/termios.h>
170 #include <dev/ic/comreg.h>
171 #if NCOM > 0
172 #include <dev/ic/comvar.h>
173 #elif NPCCOM > 0
174 #include <arch/i386/isa/pccomvar.h>
175 #endif
176 #endif
177
178
179 char machine[] = MACHINE;
180
181
182
183
184 #if NAPM > 0
185 int cpu_apmhalt = 0;
186 #endif
187
188 #ifdef USER_LDT
189 int user_ldt_enable = 0;
190 #endif
191
192 #ifndef BUFCACHEPERCENT
193 #define BUFCACHEPERCENT 10
194 #endif
195
196 #ifdef BUFPAGES
197 int bufpages = BUFPAGES;
198 #else
199 int bufpages = 0;
200 #endif
201 int bufcachepercent = BUFCACHEPERCENT;
202
203 extern int boothowto;
204 int physmem;
205
206 struct dumpmem {
207 paddr_t start;
208 paddr_t end;
209 } dumpmem[VM_PHYSSEG_MAX];
210 u_int ndumpmem;
211
212
213
214
215 u_long dumpmag = 0x8fca0101;
216 int dumpsize = 0;
217 long dumplo = 0;
218
219 int cpu_class;
220 int i386_fpu_present;
221 int i386_fpu_exception;
222 int i386_fpu_fdivbug;
223
224 int i386_use_fxsave;
225 int i386_has_sse;
226 int i386_has_sse2;
227 int i386_has_xcrypt;
228
229 bootarg_t *bootargp;
230 paddr_t avail_end;
231
232 struct vm_map *exec_map = NULL;
233 struct vm_map *phys_map = NULL;
234
235 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
236 int p4_model;
237 int p3_early;
238 void (*update_cpuspeed)(void) = NULL;
239 #endif
240 int kbd_reset;
241
242 #if !defined(SMALL_KERNEL)
243 int bus_clock;
244 #endif
245 void (*setperf_setup)(struct cpu_info *);
246 int setperf_prio = 0;
247
248 void (*cpusensors_setup)(struct cpu_info *);
249
250 void (*delay_func)(int) = i8254_delay;
251 void (*initclock_func)(void) = i8254_initclocks;
252
253
254
255
256
257
258
259
260
261
262
263
264
265 static long ioport_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
266 static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
267 struct extent *ioport_ex;
268 struct extent *iomem_ex;
269 static int ioport_malloc_safe;
270
271 caddr_t allocsys(caddr_t);
272 void setup_buffers(void);
273 void dumpsys(void);
274 int cpu_dump(void);
275 void init386(paddr_t);
276 void consinit(void);
277 void (*cpuresetfn)(void);
278
279 int bus_mem_add_mapping(bus_addr_t, bus_size_t,
280 int, bus_space_handle_t *);
281 int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *,
282 bus_size_t, struct proc *, int, paddr_t *, int *, int);
283
284 #ifdef KGDB
285 #ifndef KGDB_DEVNAME
286 #ifdef __i386__
287 #define KGDB_DEVNAME "pccom"
288 #else
289 #define KGDB_DEVNAME "com"
290 #endif
291 #endif
292 char kgdb_devname[] = KGDB_DEVNAME;
293 #if (NCOM > 0 || NPCCOM > 0)
294 #ifndef KGDBADDR
295 #define KGDBADDR 0x3f8
296 #endif
297 int comkgdbaddr = KGDBADDR;
298 #ifndef KGDBRATE
299 #define KGDBRATE TTYDEF_SPEED
300 #endif
301 int comkgdbrate = KGDBRATE;
302 #ifndef KGDBMODE
303 #define KGDBMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)
304 #endif
305 int comkgdbmode = KGDBMODE;
306 #endif
307 void kgdb_port_init(void);
308 #endif
309
310 #ifdef APERTURE
311 #ifdef INSECURE
312 int allowaperture = 1;
313 #else
314 int allowaperture = 0;
315 #endif
316 #endif
317
318 void winchip_cpu_setup(struct cpu_info *);
319 void amd_family5_setperf_setup(struct cpu_info *);
320 void amd_family5_setup(struct cpu_info *);
321 void amd_family6_setperf_setup(struct cpu_info *);
322 void amd_family6_setup(struct cpu_info *);
323 void cyrix3_setperf_setup(struct cpu_info *);
324 void cyrix3_cpu_setup(struct cpu_info *);
325 void cyrix6x86_cpu_setup(struct cpu_info *);
326 void natsem6x86_cpu_setup(struct cpu_info *);
327 void intel586_cpu_setup(struct cpu_info *);
328 void intel686_cpusensors_setup(struct cpu_info *);
329 void intel686_setperf_setup(struct cpu_info *);
330 void intel686_common_cpu_setup(struct cpu_info *);
331 void intel686_cpu_setup(struct cpu_info *);
332 void intel686_p4_cpu_setup(struct cpu_info *);
333 void intelcore_update_sensor(void *);
334 void tm86_cpu_setup(struct cpu_info *);
335 char * intel686_cpu_name(int);
336 char * cyrix3_cpu_name(int, int);
337 char * tm86_cpu_name(int);
338 void cyrix3_get_bus_clock(struct cpu_info *);
339 void p4_get_bus_clock(struct cpu_info *);
340 void p3_get_bus_clock(struct cpu_info *);
341 void p4_update_cpuspeed(void);
342 void p3_update_cpuspeed(void);
343 int pentium_cpuspeed(int *);
344
345 static __inline u_char
346 cyrix_read_reg(u_char reg)
347 {
348 outb(0x22, reg);
349 return inb(0x23);
350 }
351
352 static __inline void
353 cyrix_write_reg(u_char reg, u_char data)
354 {
355 outb(0x22, reg);
356 outb(0x23, data);
357 }
358
359
360
361
362
363 void
364 cpuid(u_int32_t ax, u_int32_t *regs)
365 {
366 __asm __volatile(
367 "cpuid\n\t"
368 "movl %%eax, 0(%2)\n\t"
369 "movl %%ebx, 4(%2)\n\t"
370 "movl %%ecx, 8(%2)\n\t"
371 "movl %%edx, 12(%2)\n\t"
372 :"=a" (ax)
373 :"0" (ax), "S" (regs)
374 :"bx", "cx", "dx");
375 }
376
377
378
379
380 void
381 cpu_startup()
382 {
383 unsigned i;
384 caddr_t v;
385 int sz;
386 vaddr_t minaddr, maxaddr, va;
387 paddr_t pa;
388
389
390
391
392
393 pa = avail_end;
394 va = (vaddr_t)msgbufp;
395 for (i = 0; i < btoc(MSGBUFSIZE); i++) {
396 pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE);
397 va += PAGE_SIZE;
398 pa += PAGE_SIZE;
399 }
400 pmap_update(pmap_kernel());
401 initmsgbuf((caddr_t)msgbufp, round_page(MSGBUFSIZE));
402
403 printf("%s", version);
404 startrtclock();
405
406
407
408
409
410 strlcpy(curcpu()->ci_dev.dv_xname, "cpu0",
411 sizeof(curcpu()->ci_dev.dv_xname));
412 curcpu()->ci_signature = cpu_id;
413 curcpu()->ci_feature_flags = cpu_feature;
414 identifycpu(curcpu());
415
416 printf("real mem = %llu (%lluMB)\n", ctob((unsigned long long)physmem),
417 ctob((unsigned long long)physmem)/1024U/1024U);
418
419
420
421
422
423 sz = (int)allocsys((caddr_t)0);
424 if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(sz))) == 0)
425 panic("startup: no room for tables");
426 if (allocsys(v) - v != sz)
427 panic("startup: table size inconsistency");
428
429
430
431
432
433 setup_buffers();
434
435
436
437
438
439 minaddr = vm_map_min(kernel_map);
440 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
441 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
442
443
444
445
446 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
447 VM_PHYS_SIZE, 0, FALSE, NULL);
448
449 printf("avail mem = %llu (%lluMB)\n",
450 ptoa((unsigned long long)uvmexp.free),
451 ptoa((unsigned long long)uvmexp.free)/1024U/1024U);
452
453
454
455
456 bufinit();
457
458
459
460
461 if (boothowto & RB_CONFIG) {
462 #ifdef BOOT_CONFIG
463 user_config();
464 #else
465 printf("kernel does not support -c; continuing..\n");
466 #endif
467 }
468 ioport_malloc_safe = 1;
469 }
470
471
472
473
474 void
475 i386_proc0_tss_ldt_init()
476 {
477 int x;
478 struct pcb *pcb;
479
480 curpcb = pcb = &proc0.p_addr->u_pcb;
481
482 pcb->pcb_tss.tss_ioopt =
483 ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
484 for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
485 pcb->pcb_iomap[x] = 0xffffffff;
486 pcb->pcb_iomap_pad = 0xff;
487
488 pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
489 pcb->pcb_ldt = ldt;
490 pcb->pcb_cr0 = rcr0();
491 pcb->pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
492 pcb->pcb_tss.tss_esp0 = (int)proc0.p_addr + USPACE - 16;
493 proc0.p_md.md_regs = (struct trapframe *)pcb->pcb_tss.tss_esp0 - 1;
494 proc0.p_md.md_tss_sel = tss_alloc(pcb);
495
496 ltr(proc0.p_md.md_tss_sel);
497 lldt(pcb->pcb_ldt_sel);
498 }
499
500 #ifdef MULTIPROCESSOR
501 void
502 i386_init_pcb_tss_ldt(struct cpu_info *ci)
503 {
504 int x;
505 struct pcb *pcb = ci->ci_idle_pcb;
506
507 pcb->pcb_tss.tss_ioopt =
508 ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
509 for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
510 pcb->pcb_iomap[x] = 0xffffffff;
511 pcb->pcb_iomap_pad = 0xff;
512
513 pcb->pcb_ldt_sel = pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL);
514 pcb->pcb_ldt = ci->ci_ldt;
515 pcb->pcb_cr0 = rcr0();
516 ci->ci_idle_tss_sel = tss_alloc(pcb);
517 }
518 #endif
519
520
521
522
523
524
525
526
527
528
529
530 caddr_t
531 allocsys(caddr_t v)
532 {
533
534 #define valloc(name, type, num) \
535 v = (caddr_t)(((name) = (type *)v) + (num))
536
537 #ifdef SYSVMSG
538 valloc(msgpool, char, msginfo.msgmax);
539 valloc(msgmaps, struct msgmap, msginfo.msgseg);
540 valloc(msghdrs, struct msg, msginfo.msgtql);
541 valloc(msqids, struct msqid_ds, msginfo.msgmni);
542 #endif
543
544 return v;
545 }
546
547 void
548 setup_buffers()
549 {
550
551
552
553
554 if (bufpages == 0)
555 bufpages = btoc(avail_end) * bufcachepercent / 100;
556
557
558 if (bufpages >
559 (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4)
560 bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) /
561 PAGE_SIZE / 4;
562 }
563
564
565
566
567 char cpu_model[120];
568
569
570
571
572
573 const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = {
574 { CPUVENDOR_INTEL, "Intel", "386SX", CPUCLASS_386,
575 NULL},
576 { CPUVENDOR_INTEL, "Intel", "386DX", CPUCLASS_386,
577 NULL},
578 { CPUVENDOR_INTEL, "Intel", "486SX", CPUCLASS_486,
579 NULL},
580 { CPUVENDOR_INTEL, "Intel", "486DX", CPUCLASS_486,
581 NULL},
582 { CPUVENDOR_CYRIX, "Cyrix", "486DLC", CPUCLASS_486,
583 NULL},
584 { CPUVENDOR_CYRIX, "Cyrix", "6x86", CPUCLASS_486,
585 cyrix6x86_cpu_setup},
586 { CPUVENDOR_NEXGEN,"NexGen","586", CPUCLASS_386,
587 NULL},
588 };
589
590 const char *classnames[] = {
591 "386",
592 "486",
593 "586",
594 "686"
595 };
596
597 const char *modifiers[] = {
598 "",
599 "OverDrive ",
600 "Dual ",
601 ""
602 };
603
604 const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
605 {
606 "GenuineIntel",
607 CPUVENDOR_INTEL,
608 "Intel",
609
610 { {
611 CPUCLASS_486,
612 {
613 "486DX", "486DX", "486SX", "486DX2", "486SL",
614 "486SX2", 0, "486DX2 W/B",
615 "486DX4", 0, 0, 0, 0, 0, 0, 0,
616 "486"
617 },
618 NULL
619 },
620
621 {
622 CPUCLASS_586,
623 {
624 "Pentium (A-step)", "Pentium (P5)",
625 "Pentium (P54C)", "Pentium (P24T)",
626 "Pentium/MMX", "Pentium", 0,
627 "Pentium (P54C)", "Pentium/MMX",
628 0, 0, 0, 0, 0, 0, 0,
629 "Pentium"
630 },
631 intel586_cpu_setup
632 },
633
634 {
635 CPUCLASS_686,
636 {
637 "Pentium Pro", "Pentium Pro", 0,
638 "Pentium II", "Pentium Pro",
639 "Pentium II/Celeron",
640 "Celeron",
641 "Pentium III",
642 "Pentium III",
643 "Pentium M",
644 "Pentium III Xeon",
645 "Pentium III", 0,
646 "Pentium M",
647 "Core Duo/Solo", 0,
648 "Pentium Pro, II or III"
649 },
650 intel686_cpu_setup
651 },
652
653 {
654 CPUCLASS_686,
655 } ,
656
657 {
658 CPUCLASS_686,
659 } ,
660
661 {
662 CPUCLASS_686,
663 } ,
664
665 {
666 CPUCLASS_686,
667 } ,
668
669 {
670 CPUCLASS_686,
671 } ,
672
673 {
674 CPUCLASS_686,
675 } ,
676
677 {
678 CPUCLASS_686,
679 } ,
680
681 {
682 CPUCLASS_686,
683 } ,
684
685 {
686 CPUCLASS_686,
687 {
688 "Pentium 4", 0, 0, 0,
689 0, 0, 0, 0,
690 0, 0, 0, 0,
691 0, 0, 0, 0,
692 "Pentium 4"
693 },
694 intel686_p4_cpu_setup
695 } }
696 },
697 {
698 "AuthenticAMD",
699 CPUVENDOR_AMD,
700 "AMD",
701
702 { {
703 CPUCLASS_486,
704 {
705 0, 0, 0, "Am486DX2 W/T",
706 0, 0, 0, "Am486DX2 W/B",
707 "Am486DX4 W/T or Am5x86 W/T 150",
708 "Am486DX4 W/B or Am5x86 W/B 150", 0, 0,
709 0, 0, "Am5x86 W/T 133/160",
710 "Am5x86 W/B 133/160",
711 "Am486 or Am5x86"
712 },
713 NULL
714 },
715
716 {
717 CPUCLASS_586,
718 {
719 "K5", "K5", "K5", "K5", 0, 0, "K6",
720 "K6", "K6-2", "K6-III", 0, 0, 0,
721 "K6-2+/III+", 0, 0,
722 "K5 or K6"
723 },
724 amd_family5_setup
725 },
726
727 {
728 CPUCLASS_686,
729 {
730 0, "Athlon Model 1", "Athlon Model 2",
731 "Duron Model 3",
732 "Athlon Model 4",
733 0, "Athlon XP Model 6",
734 "Duron Model 7",
735 "Athlon XP Model 8",
736 0, "Athlon XP Model 10",
737 0, 0, 0, 0, 0,
738 "K7"
739 },
740 amd_family6_setup
741 },
742
743 {
744 CPUCLASS_686,
745 } ,
746
747 {
748 CPUCLASS_686,
749 } ,
750
751 {
752 CPUCLASS_686,
753 } ,
754
755 {
756 CPUCLASS_686,
757 } ,
758
759 {
760 CPUCLASS_686,
761 } ,
762
763 {
764 CPUCLASS_686,
765 } ,
766
767 {
768 CPUCLASS_686,
769 } ,
770
771 {
772 CPUCLASS_686,
773 } ,
774
775 {
776 CPUCLASS_686,
777 {
778 0, 0, 0, 0, "Athlon64",
779 "Opteron or Athlon64FX", 0, 0,
780 0, 0, 0, 0, 0, 0, 0, 0,
781 "AMD64"
782 },
783 amd_family6_setup
784 } }
785 },
786 {
787 "CyrixInstead",
788 CPUVENDOR_CYRIX,
789 "Cyrix",
790
791 { {
792 CPUCLASS_486,
793 {
794 0, 0, 0, "MediaGX", 0, 0, 0, 0, "5x86", 0, 0,
795 0, 0, 0, 0,
796 "486 class"
797 },
798 NULL
799 },
800
801 {
802 CPUCLASS_586,
803 {
804 0, 0, "6x86", 0, "GXm", 0, 0, 0, 0, 0,
805 0, 0, 0, 0, 0, 0,
806 "586 class"
807 },
808 cyrix6x86_cpu_setup
809 },
810
811 {
812 CPUCLASS_686,
813 {
814 "6x86MX", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
815 0, 0, 0, 0,
816 "686 class"
817 },
818 NULL
819 } }
820 },
821 {
822 "CentaurHauls",
823 CPUVENDOR_IDT,
824 "IDT",
825
826 { {
827 CPUCLASS_486,
828 {
829 0, 0, 0, 0, 0, 0, 0, 0,
830 0, 0, 0, 0, 0, 0, 0, 0,
831 "486 class"
832 },
833 NULL
834 },
835
836 {
837 CPUCLASS_586,
838 {
839 0, 0, 0, 0, "WinChip C6", 0, 0, 0,
840 "WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0,
841 "WinChip"
842 },
843 winchip_cpu_setup
844 },
845
846 {
847 CPUCLASS_686,
848 {
849 0, 0, 0, 0, 0, 0,
850 "C3 Samuel",
851 "C3 Samuel 2/Ezra",
852 "C3 Ezra-T",
853 "C3 Nehemiah", "C3 Esther", 0, 0, 0, 0, 0,
854 "C3"
855 },
856 cyrix3_cpu_setup
857 } }
858 },
859 {
860 "RiseRiseRise",
861 CPUVENDOR_RISE,
862 "Rise",
863
864 { {
865 CPUCLASS_486,
866 {
867 0, 0, 0, 0, 0, 0, 0, 0,
868 0, 0, 0, 0, 0, 0, 0, 0,
869 "486 class"
870 },
871 NULL
872 },
873
874 {
875 CPUCLASS_586,
876 {
877 "mP6", 0, "mP6", 0, 0, 0, 0, 0,
878 0, 0, 0, 0, 0, 0, 0, 0,
879 "mP6"
880 },
881 NULL
882 },
883
884 {
885 CPUCLASS_686,
886 {
887 0, 0, 0, 0, 0, 0, 0, 0,
888 0, 0, 0, 0, 0, 0, 0, 0,
889 "686 class"
890 },
891 NULL
892 } }
893 },
894 {
895 "GenuineTMx86",
896 CPUVENDOR_TRANSMETA,
897 "Transmeta",
898
899 { {
900 CPUCLASS_486,
901 {
902 0, 0, 0, 0, 0, 0, 0, 0,
903 0, 0, 0, 0, 0, 0, 0, 0,
904 "486 class"
905 },
906 NULL
907 },
908
909 {
910 CPUCLASS_586,
911 {
912 0, 0, 0, 0, "TMS5x00", 0, 0,
913 0, 0, 0, 0, 0, 0, 0, 0, 0,
914 "TMS5x00"
915 },
916 tm86_cpu_setup
917 },
918
919 {
920 CPUCLASS_686,
921 {
922 0, 0, 0, 0, 0, 0, 0, 0,
923 0, 0, 0, 0, 0, 0, 0, 0,
924 "686 class"
925 },
926 NULL
927 } }
928 },
929 {
930 "Geode by NSC",
931 CPUVENDOR_NS,
932 "National Semiconductor",
933
934 { {
935 CPUCLASS_486,
936 {
937 0, 0, 0, 0, 0, 0, 0, 0,
938 0, 0, 0, 0, 0, 0, 0, 0,
939 "486 class"
940 },
941 NULL
942 },
943
944 {
945 CPUCLASS_586,
946 {
947 0, 0, 0, 0, "Geode GX1", 0, 0, 0, 0, 0,
948 0, 0, 0, 0, 0, 0,
949 "586 class"
950 },
951 natsem6x86_cpu_setup
952 } }
953 },
954 {
955 "SiS SiS SiS ",
956 CPUVENDOR_SIS,
957 "SiS",
958
959 { {
960 CPUCLASS_486,
961 {
962 0, 0, 0, 0, 0, 0, 0, 0,
963 0, 0, 0, 0, 0, 0, 0, 0,
964 "486 class"
965 },
966 NULL
967 },
968
969 {
970 CPUCLASS_586,
971 {
972 "SiS55x", 0, 0, 0, 0, 0, 0, 0, 0, 0,
973 0, 0, 0, 0, 0, 0,
974 "586 class"
975 },
976 NULL
977 } }
978 }
979 };
980
981 const struct cpu_cpuid_feature i386_cpuid_features[] = {
982 { CPUID_FPU, "FPU" },
983 { CPUID_VME, "V86" },
984 { CPUID_DE, "DE" },
985 { CPUID_PSE, "PSE" },
986 { CPUID_TSC, "TSC" },
987 { CPUID_MSR, "MSR" },
988 { CPUID_PAE, "PAE" },
989 { CPUID_MCE, "MCE" },
990 { CPUID_CX8, "CX8" },
991 { CPUID_APIC, "APIC" },
992 { CPUID_SYS1, "SYS" },
993 { CPUID_SEP, "SEP" },
994 { CPUID_MTRR, "MTRR" },
995 { CPUID_PGE, "PGE" },
996 { CPUID_MCA, "MCA" },
997 { CPUID_CMOV, "CMOV" },
998 { CPUID_PAT, "PAT" },
999 { CPUID_PSE36, "PSE36" },
1000 { CPUID_SER, "SER" },
1001 { CPUID_CFLUSH, "CFLUSH" },
1002 { CPUID_DS, "DS" },
1003 { CPUID_ACPI, "ACPI" },
1004 { CPUID_MMX, "MMX" },
1005 { CPUID_FXSR, "FXSR" },
1006 { CPUID_SSE, "SSE" },
1007 { CPUID_SSE2, "SSE2" },
1008 { CPUID_SS, "SS" },
1009 { CPUID_HTT, "HTT" },
1010 { CPUID_TM, "TM" },
1011 { CPUID_SBF, "SBF" },
1012 { CPUID_3DNOW, "3DNOW" },
1013 };
1014
1015 const struct cpu_cpuid_feature i386_cpuid_ecxfeatures[] = {
1016 { CPUIDECX_SSE3, "SSE3" },
1017 { CPUIDECX_MWAIT, "MWAIT" },
1018 { CPUIDECX_DSCPL, "DS-CPL" },
1019 { CPUIDECX_VMX, "VMX" },
1020 { CPUIDECX_EST, "EST" },
1021 { CPUIDECX_TM2, "TM2" },
1022 { CPUIDECX_CNXTID, "CNXT-ID" },
1023 { CPUIDECX_CX16, "CX16" },
1024 { CPUIDECX_XTPR, "xTPR" },
1025 };
1026
1027 void
1028 winchip_cpu_setup(struct cpu_info *ci)
1029 {
1030 #if defined(I586_CPU)
1031
1032 switch ((ci->ci_signature >> 4) & 15) {
1033 case 4:
1034 ci->ci_feature_flags &= ~CPUID_TSC;
1035
1036 lcr4(rcr4() | CR4_TSD);
1037 printf("%s: TSC disabled\n", ci->ci_dev.dv_xname);
1038 break;
1039 }
1040 #endif
1041 }
1042
1043 #if defined(I686_CPU) && !defined(SMALL_KERNEL)
1044 void
1045 cyrix3_setperf_setup(struct cpu_info *ci)
1046 {
1047 if (cpu_ecxfeature & CPUIDECX_EST) {
1048 if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
1049 est_init(ci->ci_dev.dv_xname, CPUVENDOR_VIA);
1050 else
1051 printf("%s: Enhanced SpeedStep disabled by BIOS\n",
1052 ci->ci_dev.dv_xname);
1053 }
1054 }
1055 #endif
1056
1057 void
1058 cyrix3_cpu_setup(struct cpu_info *ci)
1059 {
1060 #if defined(I686_CPU)
1061 int model = (ci->ci_signature >> 4) & 15;
1062 int step = ci->ci_signature & 15;
1063
1064 u_int64_t msreg;
1065 u_int32_t regs[4];
1066 unsigned int val;
1067 #if !defined(SMALL_KERNEL)
1068 extern void (*pagezero)(void *, size_t);
1069 extern void i686_pagezero(void *, size_t);
1070
1071 pagezero = i686_pagezero;
1072
1073 cyrix3_get_bus_clock(ci);
1074
1075 setperf_setup = cyrix3_setperf_setup;
1076 #endif
1077
1078 switch (model) {
1079 case 6:
1080 case 7:
1081 case 8:
1082 cpuid(0x80000001, regs);
1083 val = regs[3];
1084 if (val & (1U << 31)) {
1085 cpu_feature |= CPUID_3DNOW;
1086 } else {
1087 cpu_feature &= ~CPUID_3DNOW;
1088 }
1089 break;
1090
1091 case 9:
1092 if (step < 3)
1093 break;
1094
1095
1096
1097 case 10:
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 cpuid(0xC0000000, regs);
1110 val = regs[0];
1111 if (val >= 0xC0000001) {
1112 cpuid(0xC0000001, regs);
1113 val = regs[3];
1114 } else
1115 val = 0;
1116
1117 if (val & (C3_CPUID_HAS_RNG | C3_CPUID_HAS_ACE))
1118 printf("%s:", ci->ci_dev.dv_xname);
1119
1120
1121 if (val & C3_CPUID_HAS_RNG) {
1122 extern int viac3_rnd_present;
1123
1124 if (!(val & C3_CPUID_DO_RNG)) {
1125 msreg = rdmsr(0x110B);
1126 msreg |= 0x40;
1127 wrmsr(0x110B, msreg);
1128 }
1129 viac3_rnd_present = 1;
1130 printf(" RNG");
1131 }
1132
1133
1134 if (val & C3_CPUID_HAS_ACE) {
1135 #ifdef CRYPTO
1136 if (!(val & C3_CPUID_DO_ACE)) {
1137 msreg = rdmsr(0x1107);
1138 msreg |= (0x01 << 28);
1139 wrmsr(0x1107, msreg);
1140 }
1141 i386_has_xcrypt |= C3_HAS_AES;
1142 #endif
1143 printf(" AES");
1144 }
1145
1146
1147 if (val & C3_CPUID_HAS_ACE2) {
1148 #ifdef CRYPTO
1149 if (!(val & C3_CPUID_DO_ACE2)) {
1150 msreg = rdmsr(0x1107);
1151 msreg |= (0x01 << 28);
1152 wrmsr(0x1107, msreg);
1153 }
1154 i386_has_xcrypt |= C3_HAS_AESCTR;
1155 #endif
1156 printf(" AES-CTR");
1157 }
1158
1159
1160 if (val & C3_CPUID_HAS_PHE) {
1161 #ifdef CRYPTO
1162 if (!(val & C3_CPUID_DO_PHE)) {
1163 msreg = rdmsr(0x1107);
1164 msreg |= (0x01 << 28);
1165 wrmsr(0x1107, msreg);
1166 }
1167 i386_has_xcrypt |= C3_HAS_SHA;
1168 #endif
1169 printf(" SHA1 SHA256");
1170 }
1171
1172
1173 if (val & C3_CPUID_HAS_PMM) {
1174 #ifdef CRYPTO
1175 if (!(val & C3_CPUID_DO_PMM)) {
1176 msreg = rdmsr(0x1107);
1177 msreg |= (0x01 << 28);
1178 wrmsr(0x1107, msreg);
1179 }
1180 i386_has_xcrypt |= C3_HAS_MM;
1181 #endif
1182 printf(" RSA");
1183 }
1184
1185 printf("\n");
1186 break;
1187 }
1188 #endif
1189 }
1190
1191 void
1192 cyrix6x86_cpu_setup(struct cpu_info *ci)
1193 {
1194 extern int clock_broken_latch;
1195
1196 switch ((ci->ci_signature >> 4) & 15) {
1197 case -1:
1198 case 2:
1199
1200
1201 cyrix_write_reg(0xc2, cyrix_read_reg(0xc2) | 0x08);
1202
1203 cyrix_write_reg(0xC3, cyrix_read_reg(0xC3) | 0x10);
1204
1205 cyrix_write_reg(0x31, cyrix_read_reg(0x31) | 0xf8);
1206 cyrix_write_reg(0x32, cyrix_read_reg(0x32) | 0x7f);
1207 cyrix_write_reg(0x33, cyrix_read_reg(0x33) & ~0xff);
1208 cyrix_write_reg(0x3c, cyrix_read_reg(0x3c) | 0x87);
1209
1210 cyrix_write_reg(0xC3, cyrix_read_reg(0xC3) & ~0x10);
1211
1212 printf("%s: xchg bug workaround performed\n",
1213 ci->ci_dev.dv_xname);
1214 break;
1215 case 4:
1216
1217 clock_broken_latch = 1;
1218 curcpu()->ci_feature_flags &= ~CPUID_TSC;
1219 printf("%s: TSC disabled\n", ci->ci_dev.dv_xname);
1220 break;
1221 }
1222 }
1223
1224 void
1225 natsem6x86_cpu_setup(struct cpu_info *ci)
1226 {
1227 #if defined(I586_CPU) || defined(I686_CPU)
1228 extern int clock_broken_latch;
1229 int model = (ci->ci_signature >> 4) & 15;
1230
1231 clock_broken_latch = 1;
1232 switch (model) {
1233 case 4:
1234 cpu_feature &= ~CPUID_TSC;
1235 printf("%s: TSC disabled\n", ci->ci_dev.dv_xname);
1236 break;
1237 }
1238 #endif
1239 }
1240
1241 void
1242 intel586_cpu_setup(struct cpu_info *ci)
1243 {
1244 #if defined(I586_CPU)
1245 if (!cpu_f00f_bug) {
1246 fix_f00f();
1247 printf("%s: F00F bug workaround installed\n",
1248 ci->ci_dev.dv_xname);
1249 }
1250 #endif
1251 }
1252
1253 #if !defined(SMALL_KERNEL) && defined(I586_CPU)
1254 void
1255 amd_family5_setperf_setup(struct cpu_info *ci)
1256 {
1257 k6_powernow_init();
1258 }
1259 #endif
1260
1261 void
1262 amd_family5_setup(struct cpu_info *ci)
1263 {
1264 int model = (ci->ci_signature >> 4) & 15;
1265
1266 switch (model) {
1267 case 0:
1268
1269
1270
1271
1272
1273
1274 if (cpu_feature & CPUID_APIC)
1275 cpu_feature = (cpu_feature & ~CPUID_APIC) | CPUID_PGE;
1276
1277
1278
1279
1280 break;
1281 case 12:
1282 case 13:
1283 #if !defined(SMALL_KERNEL) && defined(I586_CPU)
1284 setperf_setup = amd_family5_setperf_setup;
1285 #endif
1286 break;
1287 }
1288 }
1289
1290 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1291 void
1292 amd_family6_setperf_setup(struct cpu_info *ci)
1293 {
1294 int family = (ci->ci_signature >> 8) & 15;
1295
1296 switch (family) {
1297 case 6:
1298 k7_powernow_init();
1299 break;
1300 case 15:
1301 k8_powernow_init();
1302 break;
1303 }
1304 }
1305 #endif
1306
1307 void
1308 amd_family6_setup(struct cpu_info *ci)
1309 {
1310 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1311 extern void (*pagezero)(void *, size_t);
1312 extern void sse2_pagezero(void *, size_t);
1313 extern void i686_pagezero(void *, size_t);
1314
1315 if (cpu_feature & CPUID_SSE2)
1316 pagezero = sse2_pagezero;
1317 else
1318 pagezero = i686_pagezero;
1319
1320 setperf_setup = amd_family6_setperf_setup;
1321 #endif
1322 }
1323
1324 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335 void
1336 intelcore_update_sensor(void *args)
1337 {
1338 struct cpu_info *ci = (struct cpu_info *) args;
1339 u_int64_t msr;
1340 int max = 100;
1341
1342 if (rdmsr(MSR_TEMPERATURE_TARGET) & MSR_TEMPERATURE_TARGET_LOW_BIT)
1343 max = 85;
1344
1345 msr = rdmsr(MSR_THERM_STATUS);
1346 if (msr & MSR_THERM_STATUS_VALID_BIT) {
1347 ci->ci_sensor.value = max - MSR_THERM_STATUS_TEMP(msr);
1348
1349 ci->ci_sensor.value *= 1000000;
1350
1351 ci->ci_sensor.value += 273150000;
1352 ci->ci_sensor.flags &= ~SENSOR_FINVALID;
1353 } else {
1354 ci->ci_sensor.value = 0;
1355 ci->ci_sensor.flags |= SENSOR_FINVALID;
1356 }
1357 }
1358
1359 void
1360 intel686_cpusensors_setup(struct cpu_info *ci)
1361 {
1362 u_int regs[4];
1363
1364 if (cpuid_level < 0x06)
1365 return;
1366
1367
1368 cpuid(0x06, regs);
1369 if ((regs[0] & 0x01) != 1)
1370 return;
1371
1372
1373 strlcpy(ci->ci_sensordev.xname, ci->ci_dev.dv_xname,
1374 sizeof(ci->ci_sensordev.xname));
1375 ci->ci_sensor.type = SENSOR_TEMP;
1376 sensor_task_register(ci, intelcore_update_sensor, 5);
1377 sensor_attach(&ci->ci_sensordev, &ci->ci_sensor);
1378 sensordev_install(&ci->ci_sensordev);
1379 }
1380 #endif
1381
1382 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1383 void
1384 intel686_setperf_setup(struct cpu_info *ci)
1385 {
1386 int family = (ci->ci_signature >> 8) & 15;
1387 int step = ci->ci_signature & 15;
1388
1389 if (cpu_ecxfeature & CPUIDECX_EST) {
1390 if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
1391 est_init(ci->ci_dev.dv_xname, CPUVENDOR_INTEL);
1392 else
1393 printf("%s: Enhanced SpeedStep disabled by BIOS\n",
1394 ci->ci_dev.dv_xname);
1395 } else if ((cpu_feature & (CPUID_ACPI | CPUID_TM)) ==
1396 (CPUID_ACPI | CPUID_TM))
1397 p4tcc_init(family, step);
1398 }
1399 #endif
1400
1401 void
1402 intel686_common_cpu_setup(struct cpu_info *ci)
1403 {
1404
1405 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1406 setperf_setup = intel686_setperf_setup;
1407 cpusensors_setup = intel686_cpusensors_setup;
1408 {
1409 extern void (*pagezero)(void *, size_t);
1410 extern void sse2_pagezero(void *, size_t);
1411 extern void i686_pagezero(void *, size_t);
1412
1413 if (cpu_feature & CPUID_SSE2)
1414 pagezero = sse2_pagezero;
1415 else
1416 pagezero = i686_pagezero;
1417 }
1418 #endif
1419
1420
1421
1422 if (cpu_feature & CPUID_SEP)
1423 wrmsr(MSR_SYSENTER_CS, 0);
1424 }
1425
1426 void
1427 intel686_cpu_setup(struct cpu_info *ci)
1428 {
1429 int model = (ci->ci_signature >> 4) & 15;
1430 int step = ci->ci_signature & 15;
1431 u_quad_t msr119;
1432
1433 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1434 p3_get_bus_clock(ci);
1435 #endif
1436
1437 intel686_common_cpu_setup(ci);
1438
1439
1440
1441
1442
1443 if ((model == 1) && (step < 3))
1444 ci->ci_feature_flags &= ~CPUID_SEP;
1445
1446
1447
1448
1449 if ((model == 7) && (ci->ci_feature_flags & CPUID_SER)) {
1450 msr119 = rdmsr(MSR_BBL_CR_CTL);
1451 msr119 |= 0x0000000000200000LL;
1452 wrmsr(MSR_BBL_CR_CTL, msr119);
1453
1454 printf("%s: disabling processor serial number\n",
1455 ci->ci_dev.dv_xname);
1456 ci->ci_feature_flags &= ~CPUID_SER;
1457 ci->ci_level = 2;
1458 }
1459
1460 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1461 p3_early = (model == 8 && step == 1) ? 1 : 0;
1462 update_cpuspeed = p3_update_cpuspeed;
1463 #endif
1464 }
1465
1466 void
1467 intel686_p4_cpu_setup(struct cpu_info *ci)
1468 {
1469 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1470 p4_get_bus_clock(ci);
1471 #endif
1472
1473 intel686_common_cpu_setup(ci);
1474
1475 #if !defined(SMALL_KERNEL) && defined(I686_CPU)
1476 p4_model = (ci->ci_signature >> 4) & 15;
1477 update_cpuspeed = p4_update_cpuspeed;
1478 #endif
1479 }
1480
1481 void
1482 tm86_cpu_setup(struct cpu_info *ci)
1483 {
1484 #if !defined(SMALL_KERNEL) && defined(I586_CPU)
1485 longrun_init();
1486 #endif
1487 }
1488
1489 char *
1490 intel686_cpu_name(int model)
1491 {
1492 char *ret = NULL;
1493
1494 switch (model) {
1495 case 5:
1496 switch (cpu_cache_edx & 0xFF) {
1497 case 0x40:
1498 case 0x41:
1499 ret = "Celeron";
1500 break;
1501
1502 case 0x43:
1503 ret = "Pentium II";
1504 break;
1505 case 0x44:
1506 case 0x45:
1507 ret = "Pentium II Xeon";
1508 break;
1509 }
1510 break;
1511 case 7:
1512 switch (cpu_cache_edx & 0xFF) {
1513
1514 case 0x43:
1515 ret = "Pentium III";
1516 break;
1517 case 0x44:
1518 case 0x45:
1519 ret = "Pentium III Xeon";
1520 break;
1521 }
1522 break;
1523 }
1524
1525 return (ret);
1526 }
1527
1528 char *
1529 cyrix3_cpu_name(int model, int step)
1530 {
1531 char *name = NULL;
1532
1533 switch (model) {
1534 case 7:
1535 if (step < 8)
1536 name = "C3 Samuel 2";
1537 else
1538 name = "C3 Ezra";
1539 break;
1540 }
1541 return name;
1542 }
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559 void
1560 identifycpu(struct cpu_info *ci)
1561 {
1562 const char *name, *modifier, *vendorname, *token;
1563 int class = CPUCLASS_386, vendor, i, max;
1564 int family, model, step, modif, cachesize;
1565 const struct cpu_cpuid_nameclass *cpup = NULL;
1566 char *brandstr_from, *brandstr_to;
1567 char *cpu_device = ci->ci_dev.dv_xname;
1568 int skipspace;
1569
1570 if (cpuid_level == -1) {
1571 #ifdef DIAGNOSTIC
1572 if (cpu < 0 || cpu >=
1573 (sizeof i386_nocpuid_cpus/sizeof(struct cpu_nocpuid_nameclass)))
1574 panic("unknown cpu type %d", cpu);
1575 #endif
1576 name = i386_nocpuid_cpus[cpu].cpu_name;
1577 vendor = i386_nocpuid_cpus[cpu].cpu_vendor;
1578 vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname;
1579 model = -1;
1580 step = -1;
1581 class = i386_nocpuid_cpus[cpu].cpu_class;
1582 ci->cpu_setup = i386_nocpuid_cpus[cpu].cpu_setup;
1583 modifier = "";
1584 token = "";
1585 } else {
1586 max = sizeof (i386_cpuid_cpus) / sizeof (i386_cpuid_cpus[0]);
1587 modif = (ci->ci_signature >> 12) & 3;
1588 family = (ci->ci_signature >> 8) & 15;
1589 model = (ci->ci_signature >> 4) & 15;
1590 step = ci->ci_signature & 15;
1591 #ifdef CPUDEBUG
1592 printf("%s: family %x model %x step %x\n", cpu_device, family,
1593 model, step);
1594 printf("%s: cpuid level %d cache eax %x ebx %x ecx %x edx %x\n",
1595 cpu_device, cpuid_level, cpu_cache_eax, cpu_cache_ebx,
1596 cpu_cache_ecx, cpu_cache_edx);
1597 #endif
1598 if (family < CPU_MINFAMILY)
1599 panic("identifycpu: strange family value");
1600
1601 for (i = 0; i < max; i++) {
1602 if (!strncmp(cpu_vendor,
1603 i386_cpuid_cpus[i].cpu_id, 12)) {
1604 cpup = &i386_cpuid_cpus[i];
1605 break;
1606 }
1607 }
1608
1609 if (cpup == NULL) {
1610 vendor = CPUVENDOR_UNKNOWN;
1611 if (cpu_vendor[0] != '\0')
1612 vendorname = &cpu_vendor[0];
1613 else
1614 vendorname = "Unknown";
1615 if (family > CPU_MAXFAMILY)
1616 family = CPU_MAXFAMILY;
1617 class = family - 3;
1618 if (class > CPUCLASS_686)
1619 class = CPUCLASS_686;
1620 modifier = "";
1621 name = "";
1622 token = "";
1623 ci->cpu_setup = NULL;
1624 } else {
1625 token = cpup->cpu_id;
1626 vendor = cpup->cpu_vendor;
1627 vendorname = cpup->cpu_vendorname;
1628
1629
1630
1631
1632
1633
1634 if (vendor == CPUVENDOR_IDT && family >= 6) {
1635 vendor = CPUVENDOR_VIA;
1636 vendorname = "VIA";
1637 }
1638 modifier = modifiers[modif];
1639 if (family > CPU_MAXFAMILY) {
1640 family = CPU_MAXFAMILY;
1641 model = CPU_DEFMODEL;
1642 } else if (model > CPU_MAXMODEL)
1643 model = CPU_DEFMODEL;
1644 i = family - CPU_MINFAMILY;
1645
1646
1647 if (vendor == CPUVENDOR_INTEL && family == 6 &&
1648 (model == 5 || model == 7)) {
1649 name = intel686_cpu_name(model);
1650
1651 } else if (vendor == CPUVENDOR_VIA && family == 6 &&
1652 model == 7) {
1653 name = cyrix3_cpu_name(model, step);
1654
1655 } else if (vendor == CPUVENDOR_TRANSMETA &&
1656 family == 5 && model == 4) {
1657 name = tm86_cpu_name(model);
1658 } else
1659 name = cpup->cpu_family[i].cpu_models[model];
1660 if (name == NULL) {
1661 name = cpup->cpu_family[i].cpu_models[CPU_DEFMODEL];
1662 if (name == NULL)
1663 name = "";
1664 }
1665 class = cpup->cpu_family[i].cpu_class;
1666 ci->cpu_setup = cpup->cpu_family[i].cpu_setup;
1667 }
1668 }
1669
1670
1671 cachesize = -1;
1672 if (vendor == CPUVENDOR_INTEL && cpuid_level >= 2 && family < 0xf) {
1673 int intel_cachetable[] = { 0, 128, 256, 512, 1024, 2048 };
1674
1675 if ((cpu_cache_edx & 0xFF) >= 0x40 &&
1676 (cpu_cache_edx & 0xFF) <= 0x45)
1677 cachesize = intel_cachetable[(cpu_cache_edx & 0xFF) - 0x40];
1678 } else if (vendor == CPUVENDOR_AMD && class == CPUCLASS_686) {
1679 u_int regs[4];
1680 cpuid(0x80000000, regs);
1681 if (regs[0] >= 0x80000006) {
1682 cpuid(0x80000006, regs);
1683 cachesize = (regs[2] >> 16);
1684 }
1685 }
1686
1687
1688 brandstr_from = brandstr_to = cpu_brandstr;
1689 skipspace = 1;
1690 while (*brandstr_from != '\0') {
1691 if (!skipspace || *brandstr_from != ' ') {
1692 skipspace = 0;
1693 *(brandstr_to++) = *brandstr_from;
1694 }
1695 if (*brandstr_from == ' ')
1696 skipspace = 1;
1697 brandstr_from++;
1698 }
1699 *brandstr_to = '\0';
1700
1701 if (cpu_brandstr[0] == '\0') {
1702 snprintf(cpu_brandstr, 48 ,
1703 "%s %s%s", vendorname, modifier, name);
1704 }
1705
1706 if ((ci->ci_flags & CPUF_PRIMARY) == 0) {
1707 if (cachesize > -1) {
1708 snprintf(cpu_model, sizeof(cpu_model),
1709 "%s (%s%s%s%s-class, %dKB L2 cache)",
1710 cpu_brandstr,
1711 ((*token) ? "\"" : ""), ((*token) ? token : ""),
1712 ((*token) ? "\" " : ""), classnames[class], cachesize);
1713 } else {
1714 snprintf(cpu_model, sizeof(cpu_model),
1715 "%s (%s%s%s%s-class)",
1716 cpu_brandstr,
1717 ((*token) ? "\"" : ""), ((*token) ? token : ""),
1718 ((*token) ? "\" " : ""), classnames[class]);
1719 }
1720
1721 printf("%s: %s", cpu_device, cpu_model);
1722 }
1723
1724 #if defined(I586_CPU) || defined(I686_CPU)
1725 if (ci->ci_feature_flags && (ci->ci_feature_flags & CPUID_TSC)) {
1726
1727 calibrate_cyclecounter();
1728 if (cpuspeed > 994) {
1729 int ghz, fr;
1730
1731 ghz = (cpuspeed + 9) / 1000;
1732 fr = ((cpuspeed + 9) / 10 ) % 100;
1733 if ((ci->ci_flags & CPUF_PRIMARY) == 0) {
1734 if (fr)
1735 printf(" %d.%02d GHz", ghz, fr);
1736 else
1737 printf(" %d GHz", ghz);
1738 }
1739 } else {
1740 if ((ci->ci_flags & CPUF_PRIMARY) == 0) {
1741 printf(" %d MHz", cpuspeed);
1742 }
1743 }
1744 }
1745 #endif
1746 if ((ci->ci_flags & CPUF_PRIMARY) == 0) {
1747 printf("\n");
1748
1749 if (ci->ci_feature_flags) {
1750 int numbits = 0;
1751
1752 printf("%s: ", cpu_device);
1753 max = sizeof(i386_cpuid_features) /
1754 sizeof(i386_cpuid_features[0]);
1755 for (i = 0; i < max; i++) {
1756 if (ci->ci_feature_flags &
1757 i386_cpuid_features[i].feature_bit) {
1758 printf("%s%s", (numbits == 0 ? "" : ","),
1759 i386_cpuid_features[i].feature_name);
1760 numbits++;
1761 }
1762 }
1763 max = sizeof(i386_cpuid_ecxfeatures)
1764 / sizeof(i386_cpuid_ecxfeatures[0]);
1765 for (i = 0; i < max; i++) {
1766 if (cpu_ecxfeature &
1767 i386_cpuid_ecxfeatures[i].feature_bit) {
1768 printf("%s%s", (numbits == 0 ? "" : ","),
1769 i386_cpuid_ecxfeatures[i].feature_name);
1770 numbits++;
1771 }
1772 }
1773 printf("\n");
1774 }
1775 }
1776
1777 #ifndef MULTIPROCESSOR
1778
1779 if (ci->cpu_setup != NULL)
1780 (ci->cpu_setup)(ci);
1781 #endif
1782
1783 #ifndef SMALL_KERNEL
1784 #if defined(I586_CPU) || defined(I686_CPU)
1785 if (cpuspeed != 0 && cpu_cpuspeed == NULL)
1786 cpu_cpuspeed = pentium_cpuspeed;
1787 #endif
1788 #endif
1789
1790 cpu_class = class;
1791
1792
1793
1794
1795
1796 switch (cpu_class) {
1797 #if !defined(I486_CPU) && !defined(I586_CPU) && !defined(I686_CPU)
1798 #error No CPU classes configured.
1799 #endif
1800 #ifndef I686_CPU
1801 case CPUCLASS_686:
1802 printf("NOTICE: this kernel does not support Pentium Pro CPU class\n");
1803 #ifdef I586_CPU
1804 printf("NOTICE: lowering CPU class to i586\n");
1805 cpu_class = CPUCLASS_586;
1806 break;
1807 #endif
1808 #endif
1809 #ifndef I586_CPU
1810 case CPUCLASS_586:
1811 printf("NOTICE: this kernel does not support Pentium CPU class\n");
1812 #ifdef I486_CPU
1813 printf("NOTICE: lowering CPU class to i486\n");
1814 cpu_class = CPUCLASS_486;
1815 break;
1816 #endif
1817 #endif
1818 #ifndef I486_CPU
1819 case CPUCLASS_486:
1820 printf("NOTICE: this kernel does not support i486 CPU class\n");
1821 #endif
1822 case CPUCLASS_386:
1823 printf("NOTICE: this kernel does not support i386 CPU class\n");
1824 panic("no appropriate CPU class available");
1825 default:
1826 break;
1827 }
1828
1829 ci->cpu_class = class;
1830
1831 if (cpu == CPU_486DLC) {
1832 #ifndef CYRIX_CACHE_WORKS
1833 printf("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n");
1834 #else
1835 #ifndef CYRIX_CACHE_REALLY_WORKS
1836 printf("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n");
1837 #else
1838 printf("WARNING: CYRIX 486DLC CACHE ENABLED.\n");
1839 #endif
1840 #endif
1841 }
1842
1843
1844
1845
1846
1847 lcr0(rcr0() | CR0_WP);
1848
1849 #if defined(I686_CPU)
1850
1851
1852
1853 if (cpu_feature & CPUID_FXSR) {
1854 i386_use_fxsave = 1;
1855 lcr4(rcr4() | CR4_OSFXSR);
1856
1857
1858
1859
1860
1861 if (cpu_feature & (CPUID_SSE|CPUID_SSE2)) {
1862 if (cpu_feature & CPUID_SSE)
1863 i386_has_sse = 1;
1864 if (cpu_feature & CPUID_SSE2)
1865 i386_has_sse2 = 1;
1866 lcr4(rcr4() | CR4_OSXMMEXCPT);
1867 }
1868 } else
1869 i386_use_fxsave = 0;
1870
1871 if (vendor == CPUVENDOR_AMD)
1872 amd64_errata(ci);
1873 #endif
1874 }
1875
1876 char *
1877 tm86_cpu_name(int model)
1878 {
1879 u_int32_t regs[4];
1880 char *name = NULL;
1881
1882 cpuid(0x80860001, regs);
1883
1884 switch (model) {
1885 case 4:
1886 if (((regs[1] >> 16) & 0xff) >= 0x3)
1887 name = "TMS5800";
1888 else
1889 name = "TMS5600";
1890 }
1891
1892 return name;
1893 }
1894
1895 #ifndef SMALL_KERNEL
1896 #ifdef I686_CPU
1897 void
1898 cyrix3_get_bus_clock(struct cpu_info *ci)
1899 {
1900 u_int64_t msr;
1901 int bus;
1902
1903 msr = rdmsr(MSR_EBL_CR_POWERON);
1904 bus = (msr >> 18) & 0x3;
1905 switch (bus) {
1906 case 0:
1907 bus_clock = BUS100;
1908 break;
1909 case 1:
1910 bus_clock = BUS133;
1911 break;
1912 case 2:
1913 bus_clock = BUS200;
1914 break;
1915 case 3:
1916 bus_clock = BUS166;
1917 break;
1918 }
1919 }
1920
1921 void
1922 p4_get_bus_clock(struct cpu_info *ci)
1923 {
1924 u_int64_t msr;
1925 int model, bus;
1926
1927 model = (ci->ci_signature >> 4) & 15;
1928 msr = rdmsr(MSR_EBC_FREQUENCY_ID);
1929 if (model < 2) {
1930 bus = (msr >> 21) & 0x7;
1931 switch (bus) {
1932 case 0:
1933 bus_clock = BUS100;
1934 break;
1935 case 1:
1936 bus_clock = BUS133;
1937 break;
1938 default:
1939 printf("%s: unknown Pentium 4 (model %d) "
1940 "EBC_FREQUENCY_ID value %d\n",
1941 ci->ci_dev.dv_xname, model, bus);
1942 break;
1943 }
1944 } else {
1945 bus = (msr >> 16) & 0x7;
1946 switch (bus) {
1947 case 0:
1948 bus_clock = (model == 2) ? BUS100 : BUS266;
1949 break;
1950 case 1:
1951 bus_clock = BUS133;
1952 break;
1953 case 2:
1954 bus_clock = BUS200;
1955 break;
1956 case 3:
1957 bus_clock = BUS166;
1958 break;
1959 default:
1960 printf("%s: unknown Pentium 4 (model %d) "
1961 "EBC_FREQUENCY_ID value %d\n",
1962 ci->ci_dev.dv_xname, model, bus);
1963 break;
1964 }
1965 }
1966 }
1967
1968 void
1969 p3_get_bus_clock(struct cpu_info *ci)
1970 {
1971 u_int64_t msr;
1972 int model, bus;
1973
1974 model = (ci->ci_signature >> 4) & 15;
1975 switch (model) {
1976 case 0x9:
1977 bus_clock = BUS100;
1978 break;
1979 case 0xd:
1980 msr = rdmsr(MSR_FSB_FREQ);
1981 bus = (msr >> 0) & 0x7;
1982 switch (bus) {
1983 case 0:
1984 bus_clock = BUS100;
1985 break;
1986 case 1:
1987 bus_clock = BUS133;
1988 break;
1989 default:
1990 printf("%s: unknown Pentium M FSB_FREQ value %d",
1991 ci->ci_dev.dv_xname, bus);
1992 goto print_msr;
1993 }
1994 break;
1995 case 0xe:
1996 case 0xf:
1997 msr = rdmsr(MSR_FSB_FREQ);
1998 bus = (msr >> 0) & 0x7;
1999 switch (bus) {
2000 case 5:
2001 bus_clock = BUS100;
2002 break;
2003 case 1:
2004 bus_clock = BUS133;
2005 break;
2006 case 3:
2007 bus_clock = BUS166;
2008 break;
2009 case 2:
2010 bus_clock = BUS200;
2011 break;
2012 case 0:
2013 bus_clock = BUS266;
2014 break;
2015 case 4:
2016 bus_clock = BUS333;
2017 break;
2018 default:
2019 printf("%s: unknown Core FSB_FREQ value %d",
2020 ci->ci_dev.dv_xname, bus);
2021 goto print_msr;
2022 }
2023 break;
2024 case 0x1:
2025 case 0x3:
2026 case 0x5:
2027 case 0x6:
2028 case 0x7:
2029 case 0x8:
2030 case 0xa:
2031 case 0xb:
2032 msr = rdmsr(MSR_EBL_CR_POWERON);
2033 bus = (msr >> 18) & 0x3;
2034 switch (bus) {
2035 case 0:
2036 bus_clock = BUS66;
2037 break;
2038 case 1:
2039 bus_clock = BUS133;
2040 break;
2041 case 2:
2042 bus_clock = BUS100;
2043 break;
2044 default:
2045 printf("%s: unknown i686 EBL_CR_POWERON value %d",
2046 ci->ci_dev.dv_xname, bus);
2047 goto print_msr;
2048 }
2049 break;
2050 default:
2051 printf("%s: unknown i686 model %d, can't get bus clock",
2052 ci->ci_dev.dv_xname, model);
2053 print_msr:
2054
2055
2056
2057
2058 printf(" (0x%llx)\n", rdmsr(MSR_EBL_CR_POWERON));
2059 break;
2060 }
2061 }
2062
2063 void
2064 p4_update_cpuspeed(void)
2065 {
2066 u_int64_t msr;
2067 int mult;
2068
2069 if (bus_clock == 0) {
2070 printf("p4_update_cpuspeed: unknown bus clock\n");
2071 return;
2072 }
2073
2074 msr = rdmsr(MSR_EBC_FREQUENCY_ID);
2075 mult = ((msr >> 24) & 0xff);
2076
2077 cpuspeed = (bus_clock * mult) / 100;
2078 }
2079
2080 void
2081 p3_update_cpuspeed(void)
2082 {
2083 u_int64_t msr;
2084 int mult;
2085 const u_int8_t mult_code[] = {
2086 50, 30, 40, 0, 55, 35, 45, 0, 0, 70, 80, 60, 0, 75, 0, 65 };
2087
2088 if (bus_clock == 0) {
2089 printf("p3_update_cpuspeed: unknown bus clock\n");
2090 return;
2091 }
2092
2093 msr = rdmsr(MSR_EBL_CR_POWERON);
2094 mult = (msr >> 22) & 0xf;
2095 mult = mult_code[mult];
2096 if (!p3_early)
2097 mult += ((msr >> 27) & 0x1) * 40;
2098
2099 cpuspeed = (bus_clock * mult) / 1000;
2100 }
2101 #endif
2102
2103 #if defined(I586_CPU) || defined(I686_CPU)
2104 int
2105 pentium_cpuspeed(int *freq)
2106 {
2107 *freq = cpuspeed;
2108 return (0);
2109 }
2110 #endif
2111 #endif
2112
2113 #ifdef COMPAT_IBCS2
2114 void ibcs2_sendsig(sig_t, int, int, u_long, int, union sigval);
2115
2116 void
2117 ibcs2_sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
2118 union sigval val)
2119 {
2120 extern int bsd_to_ibcs2_sig[];
2121
2122 sendsig(catcher, bsd_to_ibcs2_sig[sig], mask, code, type, val);
2123 }
2124 #endif
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137 void
2138 aston(struct proc *p)
2139 {
2140 #ifdef MULTIPROCESSOR
2141 if (i386_atomic_testset_i(&p->p_md.md_astpending, 1) == 0 &&
2142 p->p_cpu != curcpu())
2143 i386_fast_ipi(p->p_cpu, LAPIC_IPI_AST);
2144 #else
2145 p->p_md.md_astpending = 1;
2146 #endif
2147 }
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159 void
2160 sendsig(sig_t catcher, int sig, int mask, u_long code, int type,
2161 union sigval val)
2162 {
2163 #ifdef I686_CPU
2164 extern char sigcode, sigcode_xmm;
2165 #endif
2166 struct proc *p = curproc;
2167 struct trapframe *tf = p->p_md.md_regs;
2168 struct sigframe *fp, frame;
2169 struct sigacts *psp = p->p_sigacts;
2170 register_t sp;
2171 int oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
2172
2173
2174
2175
2176 frame.sf_signum = sig;
2177
2178
2179
2180
2181 if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
2182 (psp->ps_sigonstack & sigmask(sig))) {
2183 sp = (long)psp->ps_sigstk.ss_sp + psp->ps_sigstk.ss_size;
2184 psp->ps_sigstk.ss_flags |= SS_ONSTACK;
2185 } else
2186 sp = tf->tf_esp;
2187
2188 frame.sf_fpstate = NULL;
2189 if (p->p_md.md_flags & MDP_USEDFPU) {
2190 sp -= sizeof(union savefpu);
2191 sp &= ~0xf;
2192 frame.sf_fpstate = (void *)sp;
2193 }
2194
2195 fp = (struct sigframe *)sp - 1;
2196 frame.sf_scp = &fp->sf_sc;
2197 frame.sf_sip = NULL;
2198 frame.sf_handler = catcher;
2199
2200
2201
2202
2203 frame.sf_sc.sc_err = tf->tf_err;
2204 frame.sf_sc.sc_trapno = tf->tf_trapno;
2205 frame.sf_sc.sc_onstack = oonstack;
2206 frame.sf_sc.sc_mask = mask;
2207 #ifdef VM86
2208 if (tf->tf_eflags & PSL_VM) {
2209 frame.sf_sc.sc_gs = tf->tf_vm86_gs;
2210 frame.sf_sc.sc_fs = tf->tf_vm86_fs;
2211 frame.sf_sc.sc_es = tf->tf_vm86_es;
2212 frame.sf_sc.sc_ds = tf->tf_vm86_ds;
2213 frame.sf_sc.sc_eflags = get_vflags(p);
2214 } else
2215 #endif
2216 {
2217 frame.sf_sc.sc_fs = tf->tf_fs;
2218 frame.sf_sc.sc_gs = tf->tf_gs;
2219 frame.sf_sc.sc_es = tf->tf_es;
2220 frame.sf_sc.sc_ds = tf->tf_ds;
2221 frame.sf_sc.sc_eflags = tf->tf_eflags;
2222 }
2223 frame.sf_sc.sc_edi = tf->tf_edi;
2224 frame.sf_sc.sc_esi = tf->tf_esi;
2225 frame.sf_sc.sc_ebp = tf->tf_ebp;
2226 frame.sf_sc.sc_ebx = tf->tf_ebx;
2227 frame.sf_sc.sc_edx = tf->tf_edx;
2228 frame.sf_sc.sc_ecx = tf->tf_ecx;
2229 frame.sf_sc.sc_eax = tf->tf_eax;
2230 frame.sf_sc.sc_eip = tf->tf_eip;
2231 frame.sf_sc.sc_cs = tf->tf_cs;
2232 frame.sf_sc.sc_esp = tf->tf_esp;
2233 frame.sf_sc.sc_ss = tf->tf_ss;
2234
2235 if (psp->ps_siginfo & sigmask(sig)) {
2236 frame.sf_sip = &fp->sf_si;
2237 initsiginfo(&frame.sf_si, sig, code, type, val);
2238 #ifdef VM86
2239 if (sig == SIGURG)
2240 frame.sf_si.si_trapno = code;
2241 #endif
2242 }
2243
2244
2245 if (copyout(&frame, fp, sizeof(frame)) != 0) {
2246
2247
2248
2249
2250 sigexit(p, SIGILL);
2251
2252 }
2253
2254
2255
2256
2257 tf->tf_fs = GSEL(GUDATA_SEL, SEL_UPL);
2258 tf->tf_gs = GSEL(GUDATA_SEL, SEL_UPL);
2259 tf->tf_es = GSEL(GUDATA_SEL, SEL_UPL);
2260 tf->tf_ds = GSEL(GUDATA_SEL, SEL_UPL);
2261 tf->tf_eip = p->p_sigcode;
2262 tf->tf_cs = GSEL(GUCODE_SEL, SEL_UPL);
2263 #ifdef I686_CPU
2264 if (i386_use_fxsave)
2265 tf->tf_eip += &sigcode_xmm - &sigcode;
2266 #endif
2267 tf->tf_eflags &= ~(PSL_T|PSL_VM|PSL_AC);
2268 tf->tf_esp = (int)fp;
2269 tf->tf_ss = GSEL(GUDATA_SEL, SEL_UPL);
2270 }
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282 int
2283 sys_sigreturn(struct proc *p, void *v, register_t *retval)
2284 {
2285 struct sys_sigreturn_args
2286
2287 *uap = v;
2288 struct sigcontext *scp, context;
2289 struct trapframe *tf;
2290
2291 tf = p->p_md.md_regs;
2292
2293
2294
2295
2296
2297
2298 scp = SCARG(uap, sigcntxp);
2299 if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0)
2300 return (EFAULT);
2301
2302
2303
2304
2305 #ifdef VM86
2306 if (context.sc_eflags & PSL_VM) {
2307 tf->tf_vm86_gs = context.sc_gs;
2308 tf->tf_vm86_fs = context.sc_fs;
2309 tf->tf_vm86_es = context.sc_es;
2310 tf->tf_vm86_ds = context.sc_ds;
2311 set_vflags(p, context.sc_eflags);
2312 } else
2313 #endif
2314 {
2315
2316
2317
2318
2319
2320
2321 if (((context.sc_eflags ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 ||
2322 !USERMODE(context.sc_cs, context.sc_eflags))
2323 return (EINVAL);
2324
2325 tf->tf_fs = context.sc_fs;
2326 tf->tf_gs = context.sc_gs;
2327 tf->tf_es = context.sc_es;
2328 tf->tf_ds = context.sc_ds;
2329 tf->tf_eflags = context.sc_eflags;
2330 }
2331 tf->tf_edi = context.sc_edi;
2332 tf->tf_esi = context.sc_esi;
2333 tf->tf_ebp = context.sc_ebp;
2334 tf->tf_ebx = context.sc_ebx;
2335 tf->tf_edx = context.sc_edx;
2336 tf->tf_ecx = context.sc_ecx;
2337 tf->tf_eax = context.sc_eax;
2338 tf->tf_eip = context.sc_eip;
2339 tf->tf_cs = context.sc_cs;
2340 tf->tf_esp = context.sc_esp;
2341 tf->tf_ss = context.sc_ss;
2342
2343 if (context.sc_onstack & 01)
2344 p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
2345 else
2346 p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
2347 p->p_sigmask = context.sc_mask & ~sigcantmask;
2348
2349 return (EJUSTRETURN);
2350 }
2351
2352 int waittime = -1;
2353 struct pcb dumppcb;
2354
2355 void
2356 boot(int howto)
2357 {
2358 if (cold) {
2359
2360
2361
2362
2363 if ((howto & RB_USERREQ) == 0)
2364 howto |= RB_HALT;
2365 goto haltsys;
2366 }
2367
2368 boothowto = howto;
2369 if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
2370 extern struct proc proc0;
2371
2372
2373 if (curproc == NULL)
2374 curproc = &proc0;
2375
2376 waittime = 0;
2377 vfs_shutdown();
2378
2379
2380
2381
2382 if ((howto & RB_TIMEBAD) == 0) {
2383 resettodr();
2384 } else {
2385 printf("WARNING: not updating battery clock\n");
2386 }
2387 }
2388
2389
2390 splhigh();
2391
2392
2393 if (howto & RB_DUMP)
2394 dumpsys();
2395
2396 haltsys:
2397 doshutdownhooks();
2398
2399 if (howto & RB_HALT) {
2400 #if NACPI > 0 && !defined(SMALL_KERNEL)
2401 extern int acpi_s5, acpi_enabled;
2402
2403 if (acpi_enabled) {
2404 delay(500000);
2405 if ((howto & RB_POWERDOWN) || acpi_s5)
2406 acpi_powerdown();
2407 }
2408 #endif
2409
2410 #if NAPM > 0
2411 if (howto & RB_POWERDOWN) {
2412 int rv;
2413
2414 printf("\nAttempting to power down...\n");
2415
2416
2417
2418
2419
2420
2421
2422
2423 delay(500000);
2424
2425
2426
2427
2428
2429
2430
2431
2432 if (!cpu_apmhalt) {
2433 apm_set_powstate(APM_DEV_DISK(0xff),
2434 APM_SYS_OFF);
2435 delay(500000);
2436 }
2437 rv = apm_set_powstate(APM_DEV_DISK(0xff), APM_SYS_OFF);
2438 if (rv == 0 || rv == ENXIO) {
2439 delay(500000);
2440 (void) apm_set_powstate(APM_DEV_ALLDEVS,
2441 APM_SYS_OFF);
2442 }
2443 }
2444 #endif
2445 printf("\n");
2446 printf("The operating system has halted.\n");
2447 printf("Please press any key to reboot.\n\n");
2448 cngetc();
2449 }
2450
2451 printf("rebooting...\n");
2452 cpu_reset();
2453 for(;;) ;
2454
2455 }
2456
2457
2458
2459
2460
2461
2462
2463
2464 void
2465 dumpconf(void)
2466 {
2467 int nblks;
2468 int i;
2469
2470 if (dumpdev == NODEV ||
2471 (nblks = (bdevsw[major(dumpdev)].d_psize)(dumpdev)) == 0)
2472 return;
2473 if (nblks <= ctod(1))
2474 return;
2475
2476
2477 if (dumplo < ctod(1))
2478 dumplo = ctod(1);
2479
2480 for (i = 0; i < ndumpmem; i++)
2481 dumpsize = max(dumpsize, dumpmem[i].end);
2482
2483
2484 if (dumpsize > dtoc(nblks - dumplo - 1))
2485 dumpsize = dtoc(nblks - dumplo - 1);
2486 if (dumplo < nblks - ctod(dumpsize) - 1)
2487 dumplo = nblks - ctod(dumpsize) - 1;
2488 }
2489
2490
2491
2492
2493 int
2494 cpu_dump()
2495 {
2496 int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
2497 long buf[dbtob(1) / sizeof (long)];
2498 kcore_seg_t *segp;
2499
2500 dump = bdevsw[major(dumpdev)].d_dump;
2501
2502 segp = (kcore_seg_t *)buf;
2503
2504
2505
2506
2507 CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
2508 segp->c_size = dbtob(1) - ALIGN(sizeof(*segp));
2509
2510 return (dump(dumpdev, dumplo, (caddr_t)buf, dbtob(1)));
2511 }
2512
2513
2514
2515
2516
2517
2518 static vaddr_t dumpspace;
2519
2520 vaddr_t
2521 reserve_dumppages(vaddr_t p)
2522 {
2523
2524 dumpspace = p;
2525 return (p + PAGE_SIZE);
2526 }
2527
2528 void
2529 dumpsys()
2530 {
2531 u_int i, j, npg;
2532 int maddr;
2533 daddr64_t blkno;
2534 int (*dump)(dev_t, daddr64_t, caddr_t, size_t);
2535 int error;
2536 char *str;
2537 extern int msgbufmapped;
2538
2539
2540 savectx(&dumppcb);
2541
2542 msgbufmapped = 0;
2543 if (dumpdev == NODEV)
2544 return;
2545
2546
2547
2548
2549
2550 if (dumpsize == 0)
2551 dumpconf();
2552 if (dumplo < 0)
2553 return;
2554 printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
2555
2556 error = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
2557 printf("dump ");
2558 if (error == -1) {
2559 printf("area unavailable\n");
2560 return;
2561 }
2562
2563 #if 0
2564
2565 while (sget() != NULL);
2566 #endif
2567
2568
2569 dump = bdevsw[major(dumpdev)].d_dump;
2570 error = cpu_dump();
2571 for (i = 0; !error && i < ndumpmem; i++) {
2572
2573 npg = dumpmem[i].end - dumpmem[i].start;
2574 maddr = ctob(dumpmem[i].start);
2575 blkno = dumplo + btodb(maddr) + 1;
2576 #if 0
2577 printf("(%d %lld %d) ", maddr, blkno, npg);
2578 #endif
2579 for (j = npg; j--; maddr += NBPG, blkno += btodb(NBPG)) {
2580
2581
2582 if (dbtob(blkno - dumplo) % (1024 * 1024) < NBPG)
2583 printf("%d ",
2584 (ctob(dumpsize) - maddr) / (1024 * 1024));
2585 #if 0
2586 printf("(%x %lld) ", maddr, blkno);
2587 #endif
2588 pmap_enter(pmap_kernel(), dumpspace, maddr,
2589 VM_PROT_READ, PMAP_WIRED);
2590 if ((error = (*dump)(dumpdev, blkno,
2591 (caddr_t)dumpspace, NBPG)))
2592 break;
2593
2594 #if 0
2595
2596 if (sget() != NULL) {
2597 error = EINTR;
2598 break;
2599 }
2600 #endif
2601 }
2602 }
2603
2604 switch (error) {
2605
2606 case 0: str = "succeeded\n\n"; break;
2607 case ENXIO: str = "device bad\n\n"; break;
2608 case EFAULT: str = "device not ready\n\n"; break;
2609 case EINVAL: str = "area improper\n\n"; break;
2610 case EIO: str = "i/o error\n\n"; break;
2611 case EINTR: str = "aborted from console\n\n"; break;
2612 default: str = "error %d\n\n"; break;
2613 }
2614 printf(str, error);
2615
2616 delay(5000000);
2617 }
2618
2619
2620
2621
2622 void
2623 setregs(struct proc *p, struct exec_package *pack, u_long stack,
2624 register_t *retval)
2625 {
2626 struct pcb *pcb = &p->p_addr->u_pcb;
2627 struct pmap *pmap = vm_map_pmap(&p->p_vmspace->vm_map);
2628 struct trapframe *tf = p->p_md.md_regs;
2629
2630 #if NNPX > 0
2631
2632 if (pcb->pcb_fpcpu != NULL)
2633 npxsave_proc(p, 0);
2634 #endif
2635
2636 #ifdef USER_LDT
2637 pmap_ldt_cleanup(p);
2638 #endif
2639
2640
2641
2642
2643
2644
2645 setsegment(&pmap->pm_codeseg, 0, atop(I386_MAX_EXE_ADDR) - 1,
2646 SDT_MEMERA, SEL_UPL, 1, 1);
2647
2648
2649
2650
2651
2652 curcpu()->ci_gdt[GUCODE_SEL].sd = pcb->pcb_ldt[LUCODE_SEL].sd =
2653 pmap->pm_codeseg;
2654
2655
2656
2657
2658 pmap->pm_hiexec = 0;
2659
2660 p->p_md.md_flags &= ~MDP_USEDFPU;
2661 if (i386_use_fxsave) {
2662 pcb->pcb_savefpu.sv_xmm.sv_env.en_cw = __OpenBSD_NPXCW__;
2663 pcb->pcb_savefpu.sv_xmm.sv_env.en_mxcsr = __INITIAL_MXCSR__;
2664 } else
2665 pcb->pcb_savefpu.sv_87.sv_env.en_cw = __OpenBSD_NPXCW__;
2666
2667 tf->tf_fs = LSEL(LUDATA_SEL, SEL_UPL);
2668 tf->tf_gs = LSEL(LUDATA_SEL, SEL_UPL);
2669 tf->tf_es = LSEL(LUDATA_SEL, SEL_UPL);
2670 tf->tf_ds = LSEL(LUDATA_SEL, SEL_UPL);
2671 tf->tf_ebp = 0;
2672 tf->tf_ebx = (int)PS_STRINGS;
2673 tf->tf_eip = pack->ep_entry;
2674 tf->tf_cs = LSEL(LUCODE_SEL, SEL_UPL);
2675 tf->tf_eflags = PSL_USERSET;
2676 tf->tf_esp = stack;
2677 tf->tf_ss = LSEL(LUDATA_SEL, SEL_UPL);
2678
2679 retval[1] = 0;
2680 }
2681
2682
2683
2684
2685
2686 union descriptor ldt[NLDT];
2687 struct gate_descriptor idt_region[NIDT];
2688 struct gate_descriptor *idt = idt_region;
2689
2690 extern struct user *proc0paddr;
2691
2692 void
2693 setgate(struct gate_descriptor *gd, void *func, int args, int type, int dpl,
2694 int seg)
2695 {
2696
2697 gd->gd_looffset = (int)func;
2698 gd->gd_selector = GSEL(seg, SEL_KPL);
2699 gd->gd_stkcpy = args;
2700 gd->gd_xx = 0;
2701 gd->gd_type = type;
2702 gd->gd_dpl = dpl;
2703 gd->gd_p = 1;
2704 gd->gd_hioffset = (int)func >> 16;
2705 }
2706
2707 void
2708 unsetgate(struct gate_descriptor *gd)
2709 {
2710 gd->gd_p = 0;
2711 gd->gd_hioffset = 0;
2712 gd->gd_looffset = 0;
2713 gd->gd_selector = 0;
2714 gd->gd_xx = 0;
2715 gd->gd_stkcpy = 0;
2716 gd->gd_type = 0;
2717 gd->gd_dpl = 0;
2718 }
2719
2720 void
2721 setregion(struct region_descriptor *rd, void *base, size_t limit)
2722 {
2723
2724 rd->rd_limit = (int)limit;
2725 rd->rd_base = (int)base;
2726 }
2727
2728 void
2729 setsegment(struct segment_descriptor *sd, void *base, size_t limit, int type,
2730 int dpl, int def32, int gran)
2731 {
2732
2733 sd->sd_lolimit = (int)limit;
2734 sd->sd_lobase = (int)base;
2735 sd->sd_type = type;
2736 sd->sd_dpl = dpl;
2737 sd->sd_p = 1;
2738 sd->sd_hilimit = (int)limit >> 16;
2739 sd->sd_xx = 0;
2740 sd->sd_def32 = def32;
2741 sd->sd_gran = gran;
2742 sd->sd_hibase = (int)base >> 24;
2743 }
2744
2745 #define IDTVEC(name) __CONCAT(X, name)
2746 extern int IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
2747 IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
2748 IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), IDTVEC(page),
2749 IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), IDTVEC(syscall), IDTVEC(mchk),
2750 IDTVEC(osyscall), IDTVEC(simd);
2751
2752 #if defined(I586_CPU)
2753 extern int IDTVEC(f00f_redirect);
2754
2755 int cpu_f00f_bug = 0;
2756
2757 void
2758 fix_f00f(void)
2759 {
2760 struct region_descriptor region;
2761 vaddr_t va;
2762 void *p;
2763 pt_entry_t *pte;
2764
2765
2766 va = uvm_km_zalloc(kernel_map, NBPG*2);
2767 p = (void *)(va + NBPG - 7*sizeof(*idt));
2768
2769
2770 bcopy(idt, p, sizeof(idt_region));
2771 idt = p;
2772
2773
2774 setgate(&idt[ 14], &IDTVEC(f00f_redirect), 0, SDT_SYS386TGT, SEL_KPL,
2775 GCODE_SEL);
2776
2777
2778 pte = PTE_BASE + atop(va);
2779 *pte &= ~PG_RW;
2780
2781
2782 setregion(®ion, idt, sizeof(idt_region) - 1);
2783 lidt(®ion);
2784
2785
2786 cpu_f00f_bug = 1;
2787 }
2788 #endif
2789
2790 #ifdef MULTIPROCESSOR
2791 void
2792 cpu_init_idt()
2793 {
2794 struct region_descriptor region;
2795 setregion(®ion, idt, NIDT * sizeof(idt[0]) - 1);
2796 lidt(®ion);
2797 }
2798
2799 void
2800 cpu_default_ldt(struct cpu_info *ci)
2801 {
2802 ci->ci_ldt = ldt;
2803 ci->ci_ldt_len = sizeof(ldt);
2804 }
2805
2806 void
2807 cpu_alloc_ldt(struct cpu_info *ci)
2808 {
2809 union descriptor *cpu_ldt;
2810 size_t len = sizeof(ldt);
2811
2812 cpu_ldt = (union descriptor *)uvm_km_alloc(kernel_map, len);
2813 bcopy(ldt, cpu_ldt, len);
2814 ci->ci_ldt = cpu_ldt;
2815 ci->ci_ldt_len = len;
2816 }
2817
2818 void
2819 cpu_init_ldt(struct cpu_info *ci)
2820 {
2821 setsegment(&ci->ci_gdt[GLDT_SEL].sd, ci->ci_ldt, ci->ci_ldt_len - 1,
2822 SDT_SYSLDT, SEL_KPL, 0, 0);
2823 }
2824 #endif
2825
2826 void
2827 init386(paddr_t first_avail)
2828 {
2829 int i, kb;
2830 struct region_descriptor region;
2831 bios_memmap_t *im;
2832
2833 proc0.p_addr = proc0paddr;
2834 cpu_info_primary.ci_self = &cpu_info_primary;
2835 cpu_info_primary.ci_curpcb = &proc0.p_addr->u_pcb;
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848 ioport_ex = extent_create("ioport", 0x0, 0xffff, M_DEVBUF,
2849 (caddr_t)ioport_ex_storage, sizeof(ioport_ex_storage),
2850 EX_NOCOALESCE|EX_NOWAIT);
2851 iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF,
2852 (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage),
2853 EX_NOCOALESCE|EX_NOWAIT);
2854
2855
2856 setsegment(&gdt[GCODE_SEL].sd, 0, 0xfffff, SDT_MEMERA, SEL_KPL, 1, 1);
2857 setsegment(&gdt[GICODE_SEL].sd, 0, 0xfffff, SDT_MEMERA, SEL_KPL, 1, 1);
2858 setsegment(&gdt[GDATA_SEL].sd, 0, 0xfffff, SDT_MEMRWA, SEL_KPL, 1, 1);
2859 setsegment(&gdt[GLDT_SEL].sd, ldt, sizeof(ldt) - 1, SDT_SYSLDT,
2860 SEL_KPL, 0, 0);
2861 setsegment(&gdt[GUCODE_SEL].sd, 0, atop(I386_MAX_EXE_ADDR) - 1,
2862 SDT_MEMERA, SEL_UPL, 1, 1);
2863 setsegment(&gdt[GUDATA_SEL].sd, 0, atop(VM_MAXUSER_ADDRESS) - 1,
2864 SDT_MEMRWA, SEL_UPL, 1, 1);
2865 setsegment(&gdt[GCPU_SEL].sd, &cpu_info_primary,
2866 sizeof(struct cpu_info)-1, SDT_MEMRWA, SEL_KPL, 0, 0);
2867
2868
2869 setgate(&ldt[LSYS5CALLS_SEL].gd, &IDTVEC(osyscall), 1, SDT_SYS386CGT,
2870 SEL_UPL, GCODE_SEL);
2871 ldt[LUCODE_SEL] = gdt[GUCODE_SEL];
2872 ldt[LUDATA_SEL] = gdt[GUDATA_SEL];
2873 ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL];
2874
2875
2876 setgate(&idt[ 0], &IDTVEC(div), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2877 setgate(&idt[ 1], &IDTVEC(dbg), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2878 setgate(&idt[ 2], &IDTVEC(nmi), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2879 setgate(&idt[ 3], &IDTVEC(bpt), 0, SDT_SYS386TGT, SEL_UPL, GCODE_SEL);
2880 setgate(&idt[ 4], &IDTVEC(ofl), 0, SDT_SYS386TGT, SEL_UPL, GCODE_SEL);
2881 setgate(&idt[ 5], &IDTVEC(bnd), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2882 setgate(&idt[ 6], &IDTVEC(ill), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2883 setgate(&idt[ 7], &IDTVEC(dna), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2884 setgate(&idt[ 8], &IDTVEC(dble), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2885 setgate(&idt[ 9], &IDTVEC(fpusegm), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2886 setgate(&idt[ 10], &IDTVEC(tss), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2887 setgate(&idt[ 11], &IDTVEC(missing), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2888 setgate(&idt[ 12], &IDTVEC(stk), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2889 setgate(&idt[ 13], &IDTVEC(prot), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2890 setgate(&idt[ 14], &IDTVEC(page), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2891 setgate(&idt[ 15], &IDTVEC(rsvd), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2892 setgate(&idt[ 16], &IDTVEC(fpu), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2893 setgate(&idt[ 17], &IDTVEC(align), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2894 setgate(&idt[ 18], &IDTVEC(mchk), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2895 setgate(&idt[ 19], &IDTVEC(simd), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2896 for (i = 20; i < NRSVIDT; i++)
2897 setgate(&idt[i], &IDTVEC(rsvd), 0, SDT_SYS386TGT, SEL_KPL, GCODE_SEL);
2898 for (i = NRSVIDT; i < NIDT; i++)
2899 unsetgate(&idt[i]);
2900 setgate(&idt[128], &IDTVEC(syscall), 0, SDT_SYS386TGT, SEL_UPL, GCODE_SEL);
2901
2902 setregion(®ion, gdt, NGDT * sizeof(union descriptor) - 1);
2903 lgdt(®ion);
2904 setregion(®ion, idt, sizeof(idt_region) - 1);
2905 lidt(®ion);
2906
2907 #if NISA > 0
2908 isa_defaultirq();
2909 #endif
2910
2911 consinit();
2912
2913
2914
2915
2916
2917
2918 if (offsetof(struct user, u_pcb.pcb_savefpu) & 0xf)
2919 panic("init386: pcb_savefpu not 16-byte aligned");
2920
2921
2922 pmap_bootstrap((vaddr_t)atdevbase + IOM_SIZE);
2923
2924
2925
2926
2927
2928
2929
2930 if ((bootapiver & (BAPIV_VECTOR | BAPIV_BMEMMAP)) ==
2931 (BAPIV_VECTOR | BAPIV_BMEMMAP)) {
2932 if (bootargc > NBPG)
2933 panic("too many boot args");
2934
2935 if (extent_alloc_region(iomem_ex, (paddr_t)bootargv, bootargc,
2936 EX_NOWAIT))
2937 panic("cannot reserve /boot args memory");
2938
2939 pmap_enter(pmap_kernel(), (vaddr_t)bootargp, (paddr_t)bootargv,
2940 VM_PROT_READ|VM_PROT_WRITE,
2941 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
2942
2943 bios_getopt();
2944
2945 } else
2946 panic("/boot too old: upgrade!");
2947
2948 #ifdef DIAGNOSTIC
2949 if (bios_memmap == NULL)
2950 panic("no BIOS memory map supplied");
2951 #endif
2952
2953 #if defined(MULTIPROCESSOR)
2954
2955 pmap_enter(pmap_kernel(), (u_long)vtopte(0),
2956 round_page((vaddr_t)(bootargv + bootargc)),
2957 VM_PROT_READ|VM_PROT_WRITE,
2958 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
2959 memset(vtopte(0), 0, NBPG);
2960 #endif
2961
2962
2963
2964
2965
2966 avail_end = 0;
2967 physmem = 0;
2968 #ifdef DEBUG
2969 printf("memmap:");
2970 #endif
2971 for(i = 0, im = bios_memmap; im->type != BIOS_MAP_END; im++)
2972 if (im->type == BIOS_MAP_FREE) {
2973 paddr_t a, e;
2974 #ifdef DEBUG
2975 printf(" %llx-%llx", im->addr, im->addr + im->size);
2976 #endif
2977
2978 if (im->addr >= 0x100000000ULL) {
2979 #ifdef DEBUG
2980 printf("-H");
2981 #endif
2982 continue;
2983 }
2984
2985 a = round_page(im->addr);
2986 if (im->addr + im->size <= 0xfffff000ULL)
2987 e = trunc_page(im->addr + im->size);
2988 else {
2989 #ifdef DEBUG
2990 printf("-T");
2991 #endif
2992 e = 0xfffff000;
2993 }
2994
2995
2996 if (a < 8 * NBPG)
2997 a = 8 * NBPG;
2998
2999
3000 if (a >= e || (e - a) < NBPG) {
3001 #ifdef DEBUG
3002 printf("-S");
3003 #endif
3004 continue;
3005 }
3006 if ((a > IOM_BEGIN && a < IOM_END) ||
3007 (e > IOM_BEGIN && e < IOM_END)) {
3008 #ifdef DEBUG
3009 printf("-I");
3010 #endif
3011 continue;
3012 }
3013
3014 if (extent_alloc_region(iomem_ex, a, e - a, EX_NOWAIT))
3015
3016 printf("\nWARNING: CAN'T ALLOCATE RAM (%x-%x)"
3017 " FROM IOMEM EXTENT MAP!\n", a, e);
3018
3019 physmem += atop(e - a);
3020 dumpmem[i].start = atop(a);
3021 dumpmem[i].end = atop(e);
3022 i++;
3023 avail_end = max(avail_end, e);
3024 }
3025
3026 ndumpmem = i;
3027 avail_end -= round_page(MSGBUFSIZE);
3028
3029 #ifdef DEBUG
3030 printf(": %lx\n", avail_end);
3031 #endif
3032 if (physmem < atop(4 * 1024 * 1024)) {
3033 printf("\awarning: too little memory available;"
3034 "running in degraded mode\npress a key to confirm\n\n");
3035 cngetc();
3036 }
3037
3038 #ifdef DEBUG
3039 printf("physload: ");
3040 #endif
3041 kb = atop(KERNTEXTOFF - KERNBASE);
3042 if (kb > atop(0x100000)) {
3043 paddr_t lim = atop(0x100000);
3044 #ifdef DEBUG
3045 printf(" %x-%x (<16M)", lim, kb);
3046 #endif
3047 uvm_page_physload(lim, kb, lim, kb, VM_FREELIST_FIRST16);
3048 }
3049
3050 for (i = 0; i < ndumpmem; i++) {
3051 paddr_t a, e;
3052 paddr_t lim;
3053
3054 a = dumpmem[i].start;
3055 e = dumpmem[i].end;
3056 if (a < atop(first_avail) && e > atop(first_avail))
3057 a = atop(first_avail);
3058 if (e > atop(avail_end))
3059 e = atop(avail_end);
3060
3061 if (a < e) {
3062 if (a < atop(16 * 1024 * 1024)) {
3063 lim = MIN(atop(16 * 1024 * 1024), e);
3064 #ifdef DEBUG
3065 - printf(" %x-%x (<16M)", a, lim);
3066 #endif
3067 uvm_page_physload(a, lim, a, lim,
3068 VM_FREELIST_FIRST16);
3069 if (e > lim) {
3070 #ifdef DEBUG
3071 - printf(" %x-%x", lim, e);
3072 #endif
3073 uvm_page_physload(lim, e, lim, e,
3074 VM_FREELIST_DEFAULT);
3075 }
3076 } else {
3077 #ifdef DEBUG
3078 - printf(" %x-%x", a, e);
3079 #endif
3080 uvm_page_physload(a, e, a, e,
3081 VM_FREELIST_DEFAULT);
3082 }
3083 }
3084 }
3085 #ifdef DEBUG
3086 printf("\n");
3087 #endif
3088 tlbflush();
3089 #if 0
3090 #if NISADMA > 0
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102 if (extmem > (15*1024) && extmem < (16*1024)) {
3103 printf("Warning: ignoring %dk of remapped memory\n",
3104 extmem - (15*1024));
3105 extmem = (15*1024);
3106 }
3107 #endif
3108 #endif
3109
3110 #ifdef DDB
3111 db_machine_init();
3112 ddb_init();
3113 if (boothowto & RB_KDB)
3114 Debugger();
3115 #endif
3116 #ifdef KGDB
3117 kgdb_port_init();
3118 if (boothowto & RB_KDB) {
3119 kgdb_debug_init = 1;
3120 kgdb_connect(1);
3121 }
3122 #endif
3123 }
3124
3125
3126
3127
3128
3129
3130
3131
3132 int
3133 cpu_exec_aout_makecmds(struct proc *p, struct exec_package *epp)
3134 {
3135 return ENOEXEC;
3136 }
3137
3138
3139
3140
3141
3142
3143
3144 void
3145 consinit()
3146 {
3147 static int initted;
3148
3149 if (initted)
3150 return;
3151 initted = 1;
3152 cninit();
3153 }
3154
3155 #ifdef KGDB
3156 void
3157 kgdb_port_init()
3158 {
3159
3160 #if (NCOM > 0 || NPCCOM > 0)
3161 if (!strcmp(kgdb_devname, "com") || !strcmp(kgdb_devname, "pccom")) {
3162 bus_space_tag_t tag = I386_BUS_SPACE_IO;
3163 com_kgdb_attach(tag, comkgdbaddr, comkgdbrate, COM_FREQ,
3164 comkgdbmode);
3165 }
3166 #endif
3167 }
3168 #endif
3169
3170 void
3171 cpu_reset()
3172 {
3173 struct region_descriptor region;
3174
3175 disable_intr();
3176
3177 if (cpuresetfn)
3178 (*cpuresetfn)();
3179
3180
3181
3182
3183
3184
3185 outb(IO_KBD + KBCMDP, KBC_PULSE0);
3186 delay(100000);
3187 outb(IO_KBD + KBCMDP, KBC_PULSE0);
3188 delay(100000);
3189
3190
3191
3192
3193
3194 bzero((caddr_t)idt, sizeof(idt_region));
3195 setregion(®ion, idt, sizeof(idt_region) - 1);
3196 lidt(®ion);
3197 __asm __volatile("divl %0,%1" : : "q" (0), "a" (0));
3198
3199 #if 1
3200
3201
3202
3203
3204 bzero((caddr_t)PTD, NBPG);
3205 tlbflush();
3206 #endif
3207
3208 for (;;);
3209 }
3210
3211 void
3212 cpu_initclocks(void)
3213 {
3214 (*initclock_func)();
3215
3216 if (initclock_func == i8254_initclocks)
3217 i8254_inittimecounter();
3218 else
3219 i8254_inittimecounter_simple();
3220 }
3221
3222 void
3223 need_resched(struct cpu_info *ci)
3224 {
3225 struct proc *p;
3226
3227 ci->ci_want_resched = 1;
3228
3229
3230
3231
3232
3233 if ((p = ci->ci_curproc) != NULL)
3234 aston(p);
3235 }
3236
3237 #ifdef MULTIPROCESSOR
3238
3239
3240
3241
3242 int
3243 idt_vec_alloc(int low, int high)
3244 {
3245 int vec;
3246
3247 for (vec = low; vec <= high; vec++)
3248 if (idt[vec].gd_p == 0)
3249 return (vec);
3250 return (0);
3251 }
3252
3253 void
3254 idt_vec_set(int vec, void (*function)(void))
3255 {
3256 setgate(&idt[vec], function, 0, SDT_SYS386IGT, SEL_KPL, GCODE_SEL);
3257 }
3258
3259 void
3260 idt_vec_free(int vec)
3261 {
3262 unsetgate(&idt[vec]);
3263 }
3264 #endif
3265
3266
3267
3268
3269 int
3270 cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
3271 size_t newlen, struct proc *p)
3272 {
3273 dev_t dev;
3274
3275 switch (name[0]) {
3276 case CPU_CONSDEV:
3277 if (namelen != 1)
3278 return (ENOTDIR);
3279
3280 if (cn_tab != NULL)
3281 dev = cn_tab->cn_dev;
3282 else
3283 dev = NODEV;
3284 return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
3285 #if NBIOS > 0
3286 case CPU_BIOS:
3287 return bios_sysctl(name + 1, namelen - 1, oldp, oldlenp,
3288 newp, newlen, p);
3289 #endif
3290 case CPU_BLK2CHR:
3291 if (namelen != 2)
3292 return (ENOTDIR);
3293 dev = blktochr((dev_t)name[1]);
3294 return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
3295 case CPU_CHR2BLK:
3296 if (namelen != 2)
3297 return (ENOTDIR);
3298 dev = chrtoblk((dev_t)name[1]);
3299 return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
3300 case CPU_ALLOWAPERTURE:
3301 #ifdef APERTURE
3302 if (securelevel > 0)
3303 return (sysctl_int_lower(oldp, oldlenp, newp, newlen,
3304 &allowaperture));
3305 else
3306 return (sysctl_int(oldp, oldlenp, newp, newlen,
3307 &allowaperture));
3308 #else
3309 return (sysctl_rdint(oldp, oldlenp, newp, 0));
3310 #endif
3311 case CPU_CPUVENDOR:
3312 return (sysctl_rdstring(oldp, oldlenp, newp, cpu_vendor));
3313 case CPU_CPUID:
3314 return (sysctl_rdint(oldp, oldlenp, newp, cpu_id));
3315 case CPU_CPUFEATURE:
3316 return (sysctl_rdint(oldp, oldlenp, newp, curcpu()->ci_feature_flags));
3317 #if NAPM > 0
3318 case CPU_APMWARN:
3319 return (sysctl_int(oldp, oldlenp, newp, newlen, &cpu_apmwarn));
3320 case CPU_APMHALT:
3321 return (sysctl_int(oldp, oldlenp, newp, newlen, &cpu_apmhalt));
3322 #endif
3323 case CPU_KBDRESET:
3324 if (securelevel > 0)
3325 return (sysctl_rdint(oldp, oldlenp, newp,
3326 kbd_reset));
3327 else
3328 return (sysctl_int(oldp, oldlenp, newp, newlen,
3329 &kbd_reset));
3330 #ifdef USER_LDT
3331 case CPU_USERLDT:
3332 return (sysctl_int(oldp, oldlenp, newp, newlen,
3333 &user_ldt_enable));
3334 #endif
3335 case CPU_OSFXSR:
3336 return (sysctl_rdint(oldp, oldlenp, newp, i386_use_fxsave));
3337 case CPU_SSE:
3338 return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse));
3339 case CPU_SSE2:
3340 return (sysctl_rdint(oldp, oldlenp, newp, i386_has_sse2));
3341 case CPU_XCRYPT:
3342 return (sysctl_rdint(oldp, oldlenp, newp, i386_has_xcrypt));
3343 default:
3344 return (EOPNOTSUPP);
3345 }
3346
3347 }
3348
3349 int
3350 bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int cacheable,
3351 bus_space_handle_t *bshp)
3352 {
3353 int error;
3354 struct extent *ex;
3355
3356
3357
3358
3359 switch (t) {
3360 case I386_BUS_SPACE_IO:
3361 ex = ioport_ex;
3362 break;
3363
3364 case I386_BUS_SPACE_MEM:
3365 ex = iomem_ex;
3366 break;
3367
3368 default:
3369 panic("bus_space_map: bad bus space tag");
3370 }
3371
3372
3373
3374
3375
3376 error = extent_alloc_region(ex, bpa, size,
3377 EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0));
3378 if (error)
3379 return (error);
3380
3381
3382
3383
3384 if (t == I386_BUS_SPACE_IO) {
3385 *bshp = bpa;
3386 return (0);
3387 }
3388
3389 if (IOM_BEGIN <= bpa && bpa <= IOM_END) {
3390 *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa);
3391 return (0);
3392 }
3393
3394
3395
3396
3397
3398 error = bus_mem_add_mapping(bpa, size, cacheable, bshp);
3399 if (error) {
3400 if (extent_free(ex, bpa, size, EX_NOWAIT |
3401 (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
3402 printf("bus_space_map: pa 0x%lx, size 0x%lx\n",
3403 bpa, size);
3404 printf("bus_space_map: can't free region\n");
3405 }
3406 }
3407
3408 return (error);
3409 }
3410
3411 int
3412 _bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
3413 int cacheable, bus_space_handle_t *bshp)
3414 {
3415
3416
3417
3418 if (t == I386_BUS_SPACE_IO) {
3419 *bshp = bpa;
3420 return (0);
3421 }
3422
3423
3424
3425
3426
3427 return (bus_mem_add_mapping(bpa, size, cacheable, bshp));
3428 }
3429
3430 int
3431 bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
3432 bus_size_t size, bus_size_t alignment, bus_size_t boundary,
3433 int cacheable, bus_addr_t *bpap, bus_space_handle_t *bshp)
3434 {
3435 struct extent *ex;
3436 u_long bpa;
3437 int error;
3438
3439
3440
3441
3442 switch (t) {
3443 case I386_BUS_SPACE_IO:
3444 ex = ioport_ex;
3445 break;
3446
3447 case I386_BUS_SPACE_MEM:
3448 ex = iomem_ex;
3449 break;
3450
3451 default:
3452 panic("bus_space_alloc: bad bus space tag");
3453 }
3454
3455
3456
3457
3458 if (rstart < ex->ex_start || rend > ex->ex_end)
3459 panic("bus_space_alloc: bad region start/end");
3460
3461
3462
3463
3464 error = extent_alloc_subregion(ex, rstart, rend, size, alignment, 0,
3465 boundary, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0),
3466 &bpa);
3467
3468 if (error)
3469 return (error);
3470
3471
3472
3473
3474 if (t == I386_BUS_SPACE_IO) {
3475 *bshp = *bpap = bpa;
3476 return (0);
3477 }
3478
3479
3480
3481
3482
3483 error = bus_mem_add_mapping(bpa, size, cacheable, bshp);
3484 if (error) {
3485 if (extent_free(iomem_ex, bpa, size, EX_NOWAIT |
3486 (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
3487 printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n",
3488 bpa, size);
3489 printf("bus_space_alloc: can't free region\n");
3490 }
3491 }
3492
3493 *bpap = bpa;
3494
3495 return (error);
3496 }
3497
3498 int
3499 bus_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int cacheable,
3500 bus_space_handle_t *bshp)
3501 {
3502 u_long pa, endpa;
3503 vaddr_t va;
3504 pt_entry_t *pte;
3505 bus_size_t map_size;
3506
3507 pa = trunc_page(bpa);
3508 endpa = round_page(bpa + size);
3509
3510 #ifdef DIAGNOSTIC
3511 if (endpa <= pa && endpa != 0)
3512 panic("bus_mem_add_mapping: overflow");
3513 #endif
3514
3515 map_size = endpa - pa;
3516
3517 va = uvm_km_valloc(kernel_map, map_size);
3518 if (va == 0)
3519 return (ENOMEM);
3520
3521 *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
3522
3523 for (; map_size > 0;
3524 pa += PAGE_SIZE, va += PAGE_SIZE, map_size -= PAGE_SIZE) {
3525 pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
3526
3527 pte = kvtopte(va);
3528 if (cacheable)
3529 *pte &= ~PG_N;
3530 else
3531 *pte |= PG_N;
3532 pmap_tlb_shootpage(pmap_kernel(), va);
3533 }
3534
3535 pmap_tlb_shootwait();
3536 pmap_update(pmap_kernel());
3537
3538 return 0;
3539 }
3540
3541 void
3542 bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
3543 {
3544 struct extent *ex;
3545 u_long va, endva;
3546 bus_addr_t bpa;
3547
3548
3549
3550
3551 if (t == I386_BUS_SPACE_IO) {
3552 ex = ioport_ex;
3553 bpa = bsh;
3554 } else if (t == I386_BUS_SPACE_MEM) {
3555 ex = iomem_ex;
3556 bpa = (bus_addr_t)ISA_PHYSADDR(bsh);
3557 if (IOM_BEGIN <= bpa && bpa <= IOM_END)
3558 goto ok;
3559
3560 va = trunc_page(bsh);
3561 endva = round_page(bsh + size);
3562
3563 #ifdef DIAGNOSTIC
3564 if (endva <= va)
3565 panic("bus_space_unmap: overflow");
3566 #endif
3567
3568 (void) pmap_extract(pmap_kernel(), va, &bpa);
3569 bpa += (bsh & PGOFSET);
3570
3571
3572
3573
3574 uvm_km_free(kernel_map, va, endva - va);
3575 } else
3576 panic("bus_space_unmap: bad bus space tag");
3577
3578 ok:
3579 if (extent_free(ex, bpa, size,
3580 EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
3581 printf("bus_space_unmap: %s 0x%lx, size 0x%lx\n",
3582 (t == I386_BUS_SPACE_IO) ? "port" : "pa", bpa, size);
3583 printf("bus_space_unmap: can't free region\n");
3584 }
3585 }
3586
3587 void
3588 _bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size,
3589 bus_addr_t *adrp)
3590 {
3591 u_long va, endva;
3592 bus_addr_t bpa;
3593
3594
3595
3596
3597 if (t == I386_BUS_SPACE_IO) {
3598 bpa = bsh;
3599 } else if (t == I386_BUS_SPACE_MEM) {
3600 bpa = (bus_addr_t)ISA_PHYSADDR(bsh);
3601 if (IOM_BEGIN <= bpa && bpa <= IOM_END)
3602 goto ok;
3603
3604 va = trunc_page(bsh);
3605 endva = round_page(bsh + size);
3606
3607 #ifdef DIAGNOSTIC
3608 if (endva <= va)
3609 panic("_bus_space_unmap: overflow");
3610 #endif
3611
3612 (void) pmap_extract(pmap_kernel(), va, &bpa);
3613 bpa += (bsh & PGOFSET);
3614
3615
3616
3617
3618 uvm_km_free(kernel_map, va, endva - va);
3619 } else
3620 panic("bus_space_unmap: bad bus space tag");
3621
3622 ok:
3623 if (adrp != NULL)
3624 *adrp = bpa;
3625 }
3626
3627 void
3628 bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
3629 {
3630
3631
3632 bus_space_unmap(t, bsh, size);
3633 }
3634
3635 int
3636 bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
3637 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
3638 {
3639 *nbshp = bsh + offset;
3640 return (0);
3641 }
3642
3643
3644
3645
3646
3647 int
3648 _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments,
3649 bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
3650 {
3651 struct i386_bus_dmamap *map;
3652 void *mapstore;
3653 size_t mapsize;
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667 mapsize = sizeof(struct i386_bus_dmamap) +
3668 (sizeof(bus_dma_segment_t) * (nsegments - 1));
3669 if ((mapstore = malloc(mapsize, M_DEVBUF,
3670 (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
3671 return (ENOMEM);
3672
3673 bzero(mapstore, mapsize);
3674 map = (struct i386_bus_dmamap *)mapstore;
3675 map->_dm_size = size;
3676 map->_dm_segcnt = nsegments;
3677 map->_dm_maxsegsz = maxsegsz;
3678 map->_dm_boundary = boundary;
3679 map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
3680 map->dm_mapsize = 0;
3681 map->dm_nsegs = 0;
3682
3683 *dmamp = map;
3684 return (0);
3685 }
3686
3687
3688
3689
3690
3691 void
3692 _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
3693 {
3694
3695 free(map, M_DEVBUF);
3696 }
3697
3698
3699
3700
3701
3702 int
3703 _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
3704 bus_size_t buflen, struct proc *p, int flags)
3705 {
3706 bus_addr_t lastaddr;
3707 int seg, error;
3708
3709
3710
3711
3712 map->dm_mapsize = 0;
3713 map->dm_nsegs = 0;
3714
3715 if (buflen > map->_dm_size)
3716 return (EINVAL);
3717
3718 seg = 0;
3719 error = _bus_dmamap_load_buffer(t, map, buf, buflen, p, flags,
3720 &lastaddr, &seg, 1);
3721 if (error == 0) {
3722 map->dm_mapsize = buflen;
3723 map->dm_nsegs = seg + 1;
3724 }
3725 return (error);
3726 }
3727
3728
3729
3730
3731 int
3732 _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0,
3733 int flags)
3734 {
3735 paddr_t lastaddr;
3736 int seg, error, first;
3737 struct mbuf *m;
3738
3739
3740
3741
3742 map->dm_mapsize = 0;
3743 map->dm_nsegs = 0;
3744
3745 #ifdef DIAGNOSTIC
3746 if ((m0->m_flags & M_PKTHDR) == 0)
3747 panic("_bus_dmamap_load_mbuf: no packet header");
3748 #endif
3749
3750 if (m0->m_pkthdr.len > map->_dm_size)
3751 return (EINVAL);
3752
3753 first = 1;
3754 seg = 0;
3755 error = 0;
3756 for (m = m0; m != NULL && error == 0; m = m->m_next) {
3757 if (m->m_len == 0)
3758 continue;
3759 error = _bus_dmamap_load_buffer(t, map, m->m_data, m->m_len,
3760 NULL, flags, &lastaddr, &seg, first);
3761 first = 0;
3762 }
3763 if (error == 0) {
3764 map->dm_mapsize = m0->m_pkthdr.len;
3765 map->dm_nsegs = seg + 1;
3766 }
3767 return (error);
3768 }
3769
3770
3771
3772
3773 int
3774 _bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio,
3775 int flags)
3776 {
3777 paddr_t lastaddr;
3778 int seg, i, error, first;
3779 bus_size_t minlen, resid;
3780 struct proc *p = NULL;
3781 struct iovec *iov;
3782 caddr_t addr;
3783
3784
3785
3786
3787 map->dm_mapsize = 0;
3788 map->dm_nsegs = 0;
3789
3790 resid = uio->uio_resid;
3791 iov = uio->uio_iov;
3792
3793 if (resid > map->_dm_size)
3794 return (EINVAL);
3795
3796 if (uio->uio_segflg == UIO_USERSPACE) {
3797 p = uio->uio_procp;
3798 #ifdef DIAGNOSTIC
3799 if (p == NULL)
3800 panic("_bus_dmamap_load_uio: USERSPACE but no proc");
3801 #endif
3802 }
3803
3804 first = 1;
3805 seg = 0;
3806 error = 0;
3807 for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
3808
3809
3810
3811
3812 minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
3813 addr = (caddr_t)iov[i].iov_base;
3814
3815 error = _bus_dmamap_load_buffer(t, map, addr, minlen,
3816 p, flags, &lastaddr, &seg, first);
3817 first = 0;
3818
3819 resid -= minlen;
3820 }
3821 if (error == 0) {
3822 map->dm_mapsize = uio->uio_resid;
3823 map->dm_nsegs = seg + 1;
3824 }
3825 return (error);
3826 }
3827
3828
3829
3830
3831
3832 int
3833 _bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs,
3834 int nsegs, bus_size_t size, int flags)
3835 {
3836 if (nsegs > map->_dm_segcnt || size > map->_dm_size)
3837 return (EINVAL);
3838
3839
3840
3841
3842 if (map->_dm_boundary) {
3843 bus_addr_t bmask = ~(map->_dm_boundary - 1);
3844 int i;
3845
3846 for (i = 0; i < nsegs; i++) {
3847 if (segs[i].ds_len > map->_dm_maxsegsz)
3848 return (EINVAL);
3849 if ((segs[i].ds_addr & bmask) !=
3850 ((segs[i].ds_addr + segs[i].ds_len - 1) & bmask))
3851 return (EINVAL);
3852 }
3853 }
3854
3855 bcopy(segs, map->dm_segs, nsegs * sizeof(*segs));
3856 map->dm_nsegs = nsegs;
3857 return (0);
3858 }
3859
3860
3861
3862
3863
3864 void
3865 _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
3866 {
3867
3868
3869
3870
3871
3872 map->dm_mapsize = 0;
3873 map->dm_nsegs = 0;
3874 }
3875
3876
3877
3878
3879
3880 int
3881 _bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
3882 bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
3883 int flags)
3884 {
3885
3886 return (_bus_dmamem_alloc_range(t, size, alignment, boundary,
3887 segs, nsegs, rsegs, flags, 0, trunc_page(avail_end)));
3888 }
3889
3890
3891
3892
3893
3894 void
3895 _bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
3896 {
3897 struct vm_page *m;
3898 bus_addr_t addr;
3899 struct pglist mlist;
3900 int curseg;
3901
3902
3903
3904
3905 TAILQ_INIT(&mlist);
3906 for (curseg = 0; curseg < nsegs; curseg++) {
3907 for (addr = segs[curseg].ds_addr;
3908 addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
3909 addr += PAGE_SIZE) {
3910 m = PHYS_TO_VM_PAGE(addr);
3911 TAILQ_INSERT_TAIL(&mlist, m, pageq);
3912 }
3913 }
3914
3915 uvm_pglistfree(&mlist);
3916 }
3917
3918
3919
3920
3921
3922 int
3923 _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs,
3924 size_t size, caddr_t *kvap, int flags)
3925 {
3926 vaddr_t va;
3927 bus_addr_t addr;
3928 int curseg;
3929
3930 size = round_page(size);
3931 va = uvm_km_valloc(kernel_map, size);
3932 if (va == 0)
3933 return (ENOMEM);
3934
3935 *kvap = (caddr_t)va;
3936
3937 for (curseg = 0; curseg < nsegs; curseg++) {
3938 for (addr = segs[curseg].ds_addr;
3939 addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
3940 addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) {
3941 if (size == 0)
3942 panic("_bus_dmamem_map: size botch");
3943 pmap_enter(pmap_kernel(), va, addr,
3944 VM_PROT_READ | VM_PROT_WRITE,
3945 VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED);
3946 }
3947 }
3948 pmap_update(pmap_kernel());
3949
3950 return (0);
3951 }
3952
3953
3954
3955
3956
3957 void
3958 _bus_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size)
3959 {
3960
3961 #ifdef DIAGNOSTIC
3962 if ((u_long)kva & PGOFSET)
3963 panic("_bus_dmamem_unmap");
3964 #endif
3965
3966 size = round_page(size);
3967 uvm_km_free(kernel_map, (vaddr_t)kva, size);
3968 }
3969
3970
3971
3972
3973
3974 paddr_t
3975 _bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, off_t off,
3976 int prot, int flags)
3977 {
3978 int i;
3979
3980 for (i = 0; i < nsegs; i++) {
3981 #ifdef DIAGNOSTIC
3982 if (off & PGOFSET)
3983 panic("_bus_dmamem_mmap: offset unaligned");
3984 if (segs[i].ds_addr & PGOFSET)
3985 panic("_bus_dmamem_mmap: segment unaligned");
3986 if (segs[i].ds_len & PGOFSET)
3987 panic("_bus_dmamem_mmap: segment size not multiple"
3988 " of page size");
3989 #endif
3990 if (off >= segs[i].ds_len) {
3991 off -= segs[i].ds_len;
3992 continue;
3993 }
3994
3995 return (atop(segs[i].ds_addr + off));
3996 }
3997
3998
3999 return (-1);
4000 }
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011 int
4012 _bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
4013 bus_size_t buflen, struct proc *p, int flags, paddr_t *lastaddrp, int *segp,
4014 int first)
4015 {
4016 bus_size_t sgsize;
4017 bus_addr_t curaddr, lastaddr, baddr, bmask;
4018 vaddr_t vaddr = (vaddr_t)buf;
4019 int seg;
4020 pmap_t pmap;
4021
4022 if (p != NULL)
4023 pmap = p->p_vmspace->vm_map.pmap;
4024 else
4025 pmap = pmap_kernel();
4026
4027 lastaddr = *lastaddrp;
4028 bmask = ~(map->_dm_boundary - 1);
4029
4030 for (seg = *segp; buflen > 0 ; ) {
4031
4032
4033
4034 pmap_extract(pmap, vaddr, (paddr_t *)&curaddr);
4035
4036
4037
4038
4039 sgsize = PAGE_SIZE - ((u_long)vaddr & PGOFSET);
4040 if (buflen < sgsize)
4041 sgsize = buflen;
4042
4043
4044
4045
4046 if (map->_dm_boundary > 0) {
4047 baddr = (curaddr + map->_dm_boundary) & bmask;
4048 if (sgsize > (baddr - curaddr))
4049 sgsize = (baddr - curaddr);
4050 }
4051
4052
4053
4054
4055
4056 if (first) {
4057 map->dm_segs[seg].ds_addr = curaddr;
4058 map->dm_segs[seg].ds_len = sgsize;
4059 first = 0;
4060 } else {
4061 if (curaddr == lastaddr &&
4062 (map->dm_segs[seg].ds_len + sgsize) <=
4063 map->_dm_maxsegsz &&
4064 (map->_dm_boundary == 0 ||
4065 (map->dm_segs[seg].ds_addr & bmask) ==
4066 (curaddr & bmask)))
4067 map->dm_segs[seg].ds_len += sgsize;
4068 else {
4069 if (++seg >= map->_dm_segcnt)
4070 break;
4071 map->dm_segs[seg].ds_addr = curaddr;
4072 map->dm_segs[seg].ds_len = sgsize;
4073 }
4074 }
4075
4076 lastaddr = curaddr + sgsize;
4077 vaddr += sgsize;
4078 buflen -= sgsize;
4079 }
4080
4081 *segp = seg;
4082 *lastaddrp = lastaddr;
4083
4084
4085
4086
4087 if (buflen != 0)
4088 return (EFBIG);
4089 return (0);
4090 }
4091
4092
4093
4094
4095
4096 int
4097 _bus_dmamem_alloc_range(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment,
4098 bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs,
4099 int flags, paddr_t low, paddr_t high)
4100 {
4101 paddr_t curaddr, lastaddr;
4102 struct vm_page *m;
4103 struct pglist mlist;
4104 int curseg, error;
4105
4106
4107 size = round_page(size);
4108
4109 TAILQ_INIT(&mlist);
4110
4111
4112
4113
4114 if (high <= ISA_DMA_BOUNCE_THRESHOLD || (error = uvm_pglistalloc(size,
4115 round_page(ISA_DMA_BOUNCE_THRESHOLD), high, alignment, boundary,
4116 &mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0)))
4117 error = uvm_pglistalloc(size, low, high, alignment, boundary,
4118 &mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0);
4119 if (error)
4120 return (error);
4121
4122
4123
4124
4125
4126 m = TAILQ_FIRST(&mlist);
4127 curseg = 0;
4128 lastaddr = segs[curseg].ds_addr = VM_PAGE_TO_PHYS(m);
4129 segs[curseg].ds_len = PAGE_SIZE;
4130
4131 for (m = TAILQ_NEXT(m, pageq); m != NULL; m = TAILQ_NEXT(m, pageq)) {
4132 curaddr = VM_PAGE_TO_PHYS(m);
4133 #ifdef DIAGNOSTIC
4134 if (curseg == nsegs) {
4135 printf("uvm_pglistalloc returned too many\n");
4136 panic("_bus_dmamem_alloc_range");
4137 }
4138 if (curaddr < low || curaddr >= high) {
4139 printf("uvm_pglistalloc returned non-sensical"
4140 " address 0x%lx\n", curaddr);
4141 panic("_bus_dmamem_alloc_range");
4142 }
4143 #endif
4144 if (curaddr == (lastaddr + PAGE_SIZE))
4145 segs[curseg].ds_len += PAGE_SIZE;
4146 else {
4147 curseg++;
4148 segs[curseg].ds_addr = curaddr;
4149 segs[curseg].ds_len = PAGE_SIZE;
4150 }
4151 lastaddr = curaddr;
4152 }
4153 *rsegs = curseg + 1;
4154
4155 return (0);
4156 }
4157
4158 #ifdef DIAGNOSTIC
4159 void
4160 splassert_check(int wantipl, const char *func)
4161 {
4162 if (lapic_tpr < wantipl)
4163 splassert_fail(wantipl, lapic_tpr, func);
4164 if (wantipl == IPL_NONE && curcpu()->ci_idepth != 0)
4165 splassert_fail(-1, curcpu()->ci_idepth, func);
4166 }
4167 #endif
4168
4169 #ifdef MULTIPROCESSOR
4170 void
4171 i386_intlock(int ipl)
4172 {
4173 if (ipl < IPL_SCHED)
4174 __mp_lock(&kernel_lock);
4175
4176 curcpu()->ci_idepth++;
4177 }
4178
4179 void
4180 i386_intunlock(int ipl)
4181 {
4182 curcpu()->ci_idepth--;
4183
4184 if (ipl < IPL_SCHED)
4185 __mp_unlock(&kernel_lock);
4186 }
4187
4188 void
4189 i386_softintlock(void)
4190 {
4191 __mp_lock(&kernel_lock);
4192 curcpu()->ci_idepth++;
4193 }
4194
4195 void
4196 i386_softintunlock(void)
4197 {
4198 curcpu()->ci_idepth--;
4199 __mp_unlock(&kernel_lock);
4200 }
4201 #endif
4202
4203
4204
4205
4206
4207
4208 void
4209 softintr(int sir, int vec)
4210 {
4211 __asm __volatile("orl %1, %0" : "=m" (ipending) : "ir" (sir));
4212 #ifdef MULTIPROCESSOR
4213 i82489_writereg(LAPIC_ICRLO,
4214 vec | LAPIC_DLMODE_FIXED | LAPIC_LVL_ASSERT | LAPIC_DEST_SELF);
4215 #endif
4216 }
4217
4218
4219
4220
4221 int
4222 splraise(int ncpl)
4223 {
4224 int ocpl;
4225
4226 _SPLRAISE(ocpl, ncpl);
4227 return (ocpl);
4228 }
4229
4230
4231
4232
4233
4234 void
4235 splx(int ncpl)
4236 {
4237 _SPLX(ncpl);
4238 }
4239
4240
4241
4242
4243
4244 int
4245 spllower(int ncpl)
4246 {
4247 int ocpl = lapic_tpr;
4248
4249 splx(ncpl);
4250 return (ocpl);
4251 }