wok view linld/stuff/src/_BEG.ASM @ rev 24067

linld: add cpu detection
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Jul 05 15:05:16 2021 +0000 (2021-07-05)
parents 324b3fa82b76
children 3e2a0347b2f1
line source
1 ;***************************************************************
2 ;****** This file is distributed under GPL
3 ;***************************************************************
4 ideal
5 %PAGESIZE 255
6 %crefref
7 %noincl
8 %nomacs
10 include "common.inc"
11 include "himem.inc"
12 include "isostate.inc"
14 CMDNUMCNT = 5
15 ifdef CPUTYPE
16 CMDNUMCNT = CMDNUMCNT+1
17 endif
18 ifdef QUICK_BOOT
19 CMDNUMCNT = CMDNUMCNT+2
20 endif
22 macro alloc_isostate
23 public _isostate
24 _isostate isostate <?>
25 org $-ISOSTATE_OVERLAP
26 endm
28 macro alloc_image
29 rm_size dw ? ; _imgs-4
30 rm_buf dw ? ; _imgs-2
31 global _imgs:byte
32 label _imgs byte
33 img_kernel image_himem ?
34 img_initrd image_himem ?
35 endm
37 macro alloc_cmdnum
38 global _cmdnum:word
39 label _cmdnum word
40 dd CMDNUMCNT dup(?)
41 endm
43 p8086
45 group DGROUP _TEXT,_DATA,_BSS
46 assume cs:DGROUP,ds:DGROUP
48 segment _TEXT byte public use16 'CODE'
49 ends _TEXT
51 segment _DATA byte public use16 'DATA'
52 ;global _data_start:byte
53 label _data_start byte
54 ifndef NO386
55 msg_badcpu db "I need a 386+ in real mode w/o paging"
56 ifdef VCPI
57 db " or "
58 msg_badmapping db "under VCPI 4.0+ manager with low 640k 1:1 mapping"
59 global _vcpi:byte
60 endif
61 _vcpi db 0
62 endif
64 ends _DATA
66 segment _BSS byte public use16 'BSS'
68 ifdef ISO9660
69 ifndef VCPI
70 alloc_isotate
71 else
72 room_for_isostate = 1
73 endif
74 endif
76 ifdef ISOHOOK
77 extrn _big_cmdline:byte
78 db 254 dup(?)
79 endif
80 ;global _bss_start:byte
81 label _bss_start byte
82 global stktop:byte
83 ifdef CPUTYPE
84 global _cputype:word
85 _cputype dw ?
86 endif
87 global _cpu386:byte
88 _cpu386 db ?
89 ifdef CPU64
90 org $-1
91 global _cpu_features:dword
92 _cpu_features dd ?
93 room_for_image = 1
94 else
95 alloc_image
96 endif
98 ;BSS_OVERLAP_BOOT = 1
100 ifndef BSS_OVERLAP_BOOT
102 ifdef room_for_isostate
103 alloc_isostate
104 endif
106 ifdef room_for_image
107 alloc_image
108 endif
110 alloc_cmdnum
112 endif
114 ends _BSS
116 segment _TEXT byte public use16 'CODE'
118 macro cpuid
119 db 0fh,0A2h
120 endm
122 org 100h
123 ;global _text_start:byte
124 label _text_start byte
126 ;***************************************************************
127 ; clear bss
128 ;***************************************************************
129 mov sp,offset stktop
130 mov bx, 0F000h ; cld ; cli & empty string
131 mov si,offset _bss_start
132 clearbss:
133 mov [si],bl ; clear bss + heap
134 inc si
135 jne clearbss
137 ;***************************************************************
138 ; check CPU
139 ;***************************************************************
141 ; Check for oldies
142 ifndef NO386
143 ifdef CPUTYPE
144 mov ax,100h
145 mov cl,32 ; 186+ masks with 31
146 shr ax,cl
147 endif
148 endif
149 push bx ; < 286 : flags[12..15] are forced 1
150 popf ; = 286 : flags[12..15] are forced 0, cld, cli
151 pushf ; > 286 : only flags[15] is forced 0
152 pop dx
153 add dh,bh ; 160:NS=386+, 0F0:NC=286, 1E0:NP=86/186
154 ifndef NO386
155 mov bx,offset msg_badcpu
156 js godie ;it is not a 386+, die
157 else
158 ifdef CPUTYPE
159 jc not286
160 mov ah,2
161 not286:
162 js jmp_endcpu86 ;it is not a 386+, try ELKS & co
163 else
164 js endcpu86 ;it is not a 386+, try ELKS & co
165 endif
166 endif
167 p386
168 ifdef VCPI
169 mov edx,cs
170 shl edx,4 ; edx for prepare_vcpi
171 else
172 ifndef LARGE_ZIMAGE
173 mov edx,cs
174 shl edx,4 ; edx for memcpy32
175 endif
176 endif
177 ifndef LARGE_ZIMAGE
178 extrn gdt_base_memcpy:word ; gdt_base for memcpy32
179 add [dword gdt_base_memcpy],edx
180 endif
182 ; Check for vm
183 smsw ax ;SMSW cannot be trapped! :-)
184 and al,1 ;MSW_PE
185 ; We're in vm
186 jnz check_vcpi
188 check_rm_paging:
189 ; It's a 386 in real mode, chk for paging (crazy but possible)
190 mov eax,cr0
191 inc eax ;CR0_PG to S
192 jns endcpu386
193 ifndef NO386
194 p8086
195 extrn die:near
196 godie:
197 call near die
198 else
199 jmp_endcpu86:
200 jmp endcpu86
201 endif
204 ;***************************************************************
205 ; checks for vcpi
206 ;***************************************************************
207 label check_vcpi near
208 p386
209 ifdef VCPI
210 ; Check whether it is safe to call 67h
211 xor eax,eax
212 push ds
213 mov ds,ax
214 cmp [dword 67h*4],eax
215 pop ds
216 je no_vcpi
217 mov ah,0DEh ; check for vcpi present
218 int 67h
219 or ah,ah
220 jnz no_vcpi
221 is386vcpi:
222 extrn prepare_vcpi:near
223 call prepare_vcpi
224 ; get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
225 ;extrn _get_vcpi_interface:near
226 ;call _get_vcpi_interface
227 ifndef NO386
228 mov bx,offset msg_badmapping
229 jnz no_vcpi
230 dec [byte bx+_vcpi-msg_badmapping]
231 else
232 jnz no_vcpi
233 extrn _vcpi:byte
234 dec [byte _vcpi]
235 endif
236 endif
237 no_vcpi:
238 endcpu386:
239 ifdef CPU64
240 pushfd
241 pop dx
242 pop ax
243 ifdef CPUTYPE
244 xor al,24h ; toggle CPUID feature bit & AC bit
245 else
246 xor al,20h ; toggle CPUID feature bit 21 (=> pentium+)
247 endif
248 push ax ; (toggle AC: bit 18 => 486+)
249 push dx
250 popfd
251 pushfd
252 pop dx
253 pop dx
254 xor al,dl ; clear C
255 ifdef CPUTYPE
256 cmp al,20h
257 mov ax,0400h
258 je is486
259 mov ah,3
260 is486:
261 jae set_cputype
262 xor eax,eax
263 inc ax
264 cpuid ; Basic cpuid (late 486 or Pentium)
265 xor eax,eax
266 inc ax
267 cpuid ; again cause of Nasty EMM386s
268 push eax
269 bt edx,26 ; sse2 bit
270 jnc baseInfo
271 else
272 jne @@no_cpuid ; CPUID feature bit changed ?
273 endif
274 mov eax,80000001h ; Extended Processor Info and Feature Bits (Pentium 4 or newer)
275 cpuid ; Extended cpuid (Pentium 4)
276 ifdef CPUTYPE
277 baseInfo:
278 pop ax ; base IDs
279 and ax,0FF0h ; keep FamilyID & ModelID
280 pop cx ; extended IDs
281 mov bx,cx
282 shr bx,4 ; extended FamilyID in bl
283 shr al,4 ; set base ModelID
284 cmp ah,0Fh
285 jz SetModelID
286 cmp ah,06h
287 jnz ModelIDset
288 db 3Dh ; cmp ax,0DC00h
289 SetModelID:
290 add ah,bl ; use extended FamilyID
291 shl cl,4
292 or al,cl ; use extended ModelID
293 ModelIDset:
294 set_cputype:
295 endif
296 mov dl,-1 ; set 386 flag
297 ifdef NO386
298 db 66h ; mov [_cpu_features],edx
299 @@no_cpuid:
300 mov [word _cpu_features],dx ; dl != 0
301 else
302 mov [_cpu_features],edx
303 @@no_cpuid:
304 endif
305 else
306 dec [_cpu386]
307 endif
308 endcpu86:
309 ifdef CPUTYPE
310 mov [_cputype],ax ; _cputype: FFMM or 0[1-4]00=80[1-4]86 or 0000=8086/8088
311 endif
312 p8086
314 ;***************************************************************
315 ; build argv & argc
316 ;***************************************************************
317 mov si,80h
318 ifdef ISOHOOK
319 mov bx,offset _big_cmdline
320 cmp [byte si],2
321 jnb @@user_args
322 call @set_cmdline$qpxzc
323 @@user_args:
324 endif
325 lodsb ; size 0..127
326 cbw
327 ifdef ISOHOOK
328 inc ax
329 jnz short_cmdline
330 mov si,bx
331 lodsb ; size 0..254
332 short_cmdline:
333 dec ax
334 endif
335 xchg ax,bx
336 mov [bx+si],bh ; set eos
338 ;***************************************************************
340 ifdef BSS_OVERLAP_BOOT
341 mov di,offset clean-100h
343 org $-(CMDNUMCNT*4) ; alloc_cmdnum
345 ifdef room_for_image
346 org $-2-2-(2*size image_himem) ; alloc_image
347 endif
349 ifdef room_for_isostate
350 org $+ISOSTATE_OVERLAP-size isostate
351 alloc_isostate
352 endif
354 ifdef room_for_image
355 alloc_image
356 endif
358 alloc_cmdnum
359 clean:
360 mov [di+0FFh],bh
361 dec di
362 jnz clean
363 endif
365 org $-4 ; _himem_buf
366 global _himem_buf:dword
367 _himem_buf dd ?
369 ;***************************************************************
370 extrn _bss_end:word
371 mov di,offset _bss_end
372 global _heap_top
373 org $-2
374 _heap_top dw ?
375 ;xor dx,dx
376 ;push dx ; envp (already cleared)
377 ;mov [word di],dx ; argv[0] = 0 (idem)
378 argbuild:
379 mov bx,2 ; argc * 2
380 argeos:
381 mov cx,1 ; look for a start of string
382 mov [byte si-1],bh ; mark eos
383 mov ah,20h ; space will be eos
384 arglp:
385 lodsb
386 cmp al,0h
387 je argdone
388 cmp al,20h
389 jb argeos
390 cmp al,ah
391 je argeos
392 cmp al,27h
393 je isargstr
394 cmp al,22h
395 je isargstr
396 jcxz arglp ; not start of string
397 dec si
398 ;jmp newarg
399 db 0BAh ; mov dx,im opcode
400 isargstr:
401 mov ah,al ; expected eos
402 newarg:
403 mov [word bx+di],si ; argv[argc++] = si
404 inc bx
405 inc bx
406 dec cx
407 jmp arglp
409 ;***************************************************************
410 ;_fastcall void set_cmdline(bx:const char *filename);
411 ;***************************************************************
412 global @set_cmdline$qpxzc:near
413 proc @set_cmdline$qpxzc near
414 extrn openargs:near
415 call openargs
416 jc @ret
417 mov ch,15 ; cx<4096
418 mov di,[_heap_top]
419 jmp read_cmdline ; read_cmdline(ax,di,cx)
421 endp @set_cmdline$qpxzc
423 ifdef NO386
424 ;***************************************************************
425 ;u16 topseg();
426 ;***************************************************************
427 global _topseg:near
428 proc _topseg near
430 int 12h
431 jnc @@max640k
432 mov ax,640 ; 9000
433 @@max640k:
434 dec ax
435 and al,0C0h
436 mov cl,6
437 shl ax,cl
438 @ret:
439 ret
441 endp _topseg
442 else
443 @ret:
444 ret
445 endif
447 ;***************************************************************
448 argdone:
449 ;mov [word bx+di],0 ; argv[argc] = 0
450 lea ax,[bx+di+2]
451 mov [_heap_top],ax
452 ;push di ; argv
453 ;shr bx,1
454 ;push bx ; argc
455 ifndef filearg
456 mov bx,[di+2] ; argv[1]
457 extrn openargs:near
458 call near openargs
459 jc argend
460 ;pop bx ; trash argc, argv >> 1Kb !
461 ;pop cx ; sizemax=argv
462 dec cx ; sizemax=0ffffh
463 read_cmdline:
464 mov dx,di
465 push dx
466 xchg ax,bx
467 extrn @read$cxdxbx:near ; read(fd=bx,buffer=dx,size=cx)
468 call near @read$cxdxbx
469 pop si ; si=buffer=argv
470 add di,ax
471 ifndef NO_CLOSE
472 extrn close:near
473 call near close
474 endif
475 jmp argbuild
476 argend:
477 endif
479 ;***************************************************************
480 ; extrn _main:near
481 ; call _main
482 ;never return
484 ;***************************************************************
487 ends _TEXT
490 end _text_start
492 ;###### END OF FILE ############################################