com32/chain: make raw handover use total sectors info
[syslinux.git] / core / parseconfig.inc
blob69681d94ca6eb68bcfcc8c762aa1fbe9d6b25863
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
4 ;;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
5 ;;
6 ;;   This program is free software; you can redistribute it and/or modify
7 ;;   it under the terms of the GNU General Public License as published by
8 ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9 ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
10 ;;   (at your option) any later version; incorporated herein by reference.
12 ;; -----------------------------------------------------------------------
15 ;; parseconfig.inc
17 ;; Configuration file operations
20                 section .text16
22 ; "default" or "ui" command, with level (1 = default, 2 = ui)
24 pc_default:     cmp ax,[DefaultLevel]
25                 jb skipline                     ; == call skipline + ret
26                 mov [DefaultLevel],ax
27                 mov di,default_cmd
28                 call getline
29                 mov byte [di-1],0               ; null-terminate
30                 ret
33 ; "ontimeout" command
35 pc_ontimeout:   mov di,Ontimeout
36                 call getline
37                 sub di,Ontimeout+1              ; Don't need final space
38                 mov [OntimeoutLen],di
39                 ret
42 ; "onerror" command
44 pc_onerror:     mov di,Onerror
45                 call getline
46                 sub di,Onerror
47                 mov [OnerrorLen],di
48                 ret
51 ; "append" command
53 pc_append:      cmp byte [VKernel],0
54                 ja .vk
55                 mov di,AppendBuf
56                 call getline
57                 sub di,AppendBuf
58 .app1:          mov [AppendLen],di
59                 ret
60 .vk:            mov di,VKernelBuf+vk_append     ; "append" command (vkernel)
61                 call getline
62                 sub di,VKernelBuf+vk_append
63                 cmp di,byte 2
64                 jne .app2
65                 cmp byte [VKernelBuf+vk_append],'-'
66                 jne .app2
67                 xor di,di                       ; If "append -" -> null string
68 .app2:          mov [VKernelBuf+vk_appendlen],di
69                 ret
72 ; "ipappend" command (PXELINUX only)
74 %if IS_PXELINUX
75 pc_ipappend:    call getint
76                 jc .err
77                 cmp byte [VKernel],0
78                 jne .vk
79                 mov [IPAppend],bl
80 .err:           ret
81 .vk:            mov [VKernelBuf+vk_ipappend],bl
82                 ret
83 %endif
86 ; "localboot" command
88 %if HAS_LOCALBOOT
90 pc_localboot:   call getint
91                 cmp byte [VKernel],0            ; ("label" section only)
92                 je .err
93                 mov [VKernelBuf+vk_rname],bx
94                 mov byte [VKernelBuf+vk_type],VK_LOCALBOOT
95 .err:           ret
97 %endif ; HAS_LOCALBOOT
100 ; "kernel", "config", ... command
102 pc_kernel:      cmp byte [VKernel],0
103                 je .err                         ; ("label" section only)
104                 mov [VKernelBuf+vk_type],al
105                 call pc_getline
106                 mov di,VKernelBuf+vk_rname
107                 pm_call pm_mangle_name
108 .err:           ret
111 ; "timeout", "totaltimeout" command
113 ; N.B. 1/10 s ~ 1.D2162AABh clock ticks
115 pc_timeout:     push ax
116                 call getint
117                 pop si
118                 jc .err
119                 mov eax,0D2162AABh
120                 mul ebx                         ; clock ticks per 1/10 s
121                 add ebx,edx
122                 mov [si],ebx
123 .err:           ret
127 ; "totaltimeout" command
129 pc_totaltimeout:
132 ; Generic integer variable setting commands:
133 ; "prompt", "implicit"
135 pc_setint16:
136                 push ax
137                 call getint
138                 pop si
139                 jc .err
140                 mov [si],bx
141 .err:           ret
144 ; Generic file-processing commands:
145 ; "font", "kbdmap",
147 pc_filecmd:     push ax                         ; Function to tailcall
148                 call pc_getline
149                 mov di,MNameBuf
150                 pm_call pm_mangle_name
151                 pm_call pm_searchdir
152                 jnz .ok
153                 pop ax                          ; Drop the successor function
154 .ok:            ret                             ; Tailcall if OK, error return
157 ; Commands that expect the file to be opened on top of the getc stack.
158 ; "display", "include"
160 pc_opencmd:     push ax                         ; Function to tailcall
161                 call pc_getline
162                 mov di,MNameBuf
163                 pm_call pm_mangle_name
164                 call core_open
165                 jnz .ok
166                 pop ax                          ; Drop the successor function
167 .ok:            ret                             ; Tailcall if OK, error return
170 ; "include" command (invoked from pc_opencmd)
172 pc_include:     inc word [IncludeLevel]
173 .err:           ret
176 ; "serial" command
178 pc_serial:      call getint
179                 jc .err
180                 push bx                         ; Serial port #
181                 xor eax,eax
182                 mov [FlowControl],eax           ; Default to no flow control
183                 call skipspace
184                 jc .nobaud
185                 call ungetc
186                 call getint
187                 jc .nobaud
188 .valid_baud:
189                 push ebx
190                 call skipspace
191                 jc .no_flow
192                 call ungetc
193                 call getint                     ; Hardware flow control?
194                 jnc .valid_flow
195 .no_flow:
196                 xor bx,bx                       ; Default -> no flow control
197 .valid_flow:
198                 and bh,0Fh                      ; FlowIgnore
199                 shl bh,4
200                 mov [FlowIgnore],bh
201                 mov bh,bl
202                 and bx,0F00Bh                   ; Valid bits
203                 mov [FlowControl],bx
204                 pop ebx                         ; Baud rate
205                 jmp short .parse_baud
206 .nobaud:
207                 mov ebx,DEFAULT_BAUD            ; No baud rate given
208 .parse_baud:
209                 pop di                          ; Serial port #
210                 cmp ebx,byte 75
211                 jb .err                         ; < 75 baud == bogus
212                 mov eax,BAUD_DIVISOR
213                 cdq
214                 div ebx
215                 mov [BaudDivisor],ax
216                 push ax                         ; Baud rate divisor
217                 cmp di,3
218                 ja .port_is_io                  ; If port > 3 then port is I/O addr
219                 shl di,1
220                 mov di,[di+serial_base]         ; Get the I/O port from the BIOS
221 .port_is_io:
222                 mov [SerialPort],di
224                 ;
225                 ; Begin code to actually set up the serial port
226                 ;
227                 call sirq_cleanup_nowipe        ; Cleanup existing IRQ handler
229                 lea dx,[di+3]                   ; DX -> LCR
230                 mov al,83h                      ; Enable DLAB
231                 slow_out dx,al
233                 pop ax                          ; Divisor
234                 mov dx,di                       ; DX -> LS
235                 slow_out dx,al
237                 inc dx                          ; DX -> MS
238                 mov al,ah
239                 slow_out dx,al
241                 mov al,03h                      ; Disable DLAB
242                 inc dx                          ; DX -> LCR
243                 inc dx
244                 slow_out dx,al
246                 in al,dx                ; Read back LCR (detect missing hw)
247                 cmp al,03h              ; If nothing here we'll read 00 or FF
248                 jne .err                ; Assume serial port busted
249                 dec dx                          ; DX -> IIR/FCR
250                 mov al,01h
251                 slow_out dx,al                  ; Enable FIFOs if present
252                 in al,dx
253                 cmp al,0C0h                     ; FIFOs enabled and usable?
254                 jae .fifo_ok
255                 xor ax,ax                       ; Disable FIFO if unusable
256                 slow_out dx,al
257 .fifo_ok:
259                 inc dx
260                 inc dx                          ; DX -> MCR
261                 mov al,[FlowOutput]             ; Assert bits
262                 slow_out dx,al
264                 ; Enable interrupts if requested
265                 test al,8
266                 jz .noirq
267                 call sirq_install
268 .noirq:
270                 ; Show some life
271                 cmp byte [SerialNotice],0
272                 je .notfirst
273                 mov byte [SerialNotice],0
275                 mov si,syslinux_banner
276                 call write_serial_str
277                 mov si,copyright_str
278                 call write_serial_str
279 .notfirst:
280                 ret
282 .err:
283                 mov [SerialPort], word 0
284                 ret
287 ; Store mangled filename command (F-keys, "initrd")
289 pc_filename:    push ax
290                 call pc_getline
291                 pop di
292                 pm_call pm_mangle_name          ; Mangle file name
293                 ret
296 ; "label" command
298 pc_label:       call commit_vk                  ; Commit any current vkernel
299                 mov byte [InitRD+NULLOFFSET],NULLFILE   ; No "initrd" statement
300                 mov di,VKernelBuf               ; Erase the vkernelbuf for better compression
301                 mov cx,(vk_size >> 1)
302                 xor ax,ax
303                 rep stosw
304                 call pc_getline
305                 mov di,VKernelBuf+vk_vname
306                 mov cx,FILENAME_MAX-1
307 .loop:
308                 lodsb
309                 cmp al,' '
310                 jna .done
311                 stosb
312                 loop .loop
313 .done:
314                 mov byte [VKernel],1            ; We've seen a "label" statement
315                 mov si,VKernelBuf+vk_vname      ; By default, rname == mangled vname
316                 mov di,VKernelBuf+vk_rname
317                 pm_call pm_mangle_name
318                 mov si,AppendBuf                ; Default append==global append
319                 mov di,VKernelBuf+vk_append
320                 mov cx,[AppendLen]
321                 mov [VKernelBuf+vk_appendlen],cx
322                 rep movsb
323 %if IS_PXELINUX                                 ; PXELINUX only
324                 mov al,[IPAppend]               ; Default ipappend==global ipappend
325                 mov [VKernelBuf+vk_ipappend],al
326 %endif
327                 ret
330 ; "say" command
332 pc_say:         call pc_getline                 ; "say" command
333                 call writestr
334                 jmp crlf                        ; tailcall
337 ; "text" command; ignore everything until we get an "endtext" line
339 pc_text:        call skipline                   ; Ignore rest of line
340 .loop:
341                 call pc_getline
342                 jc .eof
344                 ; Leading spaces are already removed...
345                 lodsd
346                 and eax,0xdfdfdfdf              ; Upper case
347                 cmp eax,'ENDT'
348                 jne .loop
349                 lodsd
350                 and eax,0x00dfdfdf              ; Upper case and mask
351                 cmp eax,'EXT'
352                 jne .loop
353                 ; If we get here we hit ENDTEXT
354 .eof:
355                 ret
358 ; Comment line
360 pc_comment:     ; Fall into pc_getline
363 ; Common subroutine: load line into trackbuf; returns with SI -> trackbuf
364 ; CF is set on EOF.
366 pc_getline:     mov di,trackbuf
367                 push di
368                 call getline
369                 mov byte [di],0                 ; Null-terminate
370                 pop si
371                 ret
374 ; Main loop for configuration file parsing
376 parse_config:
377                 mov di,VKernelBuf               ; Clear VKernelBuf at start
378                 xor ax,ax
379                 mov cx,vk_size
380                 rep stosb
382 .again:
383                 call getcommand                 ; Parse one command
384                 jnc .again                      ; If not EOF...
385                 call close
386                 dec word [IncludeLevel]         ; Still parsing?
387                 jnz .again
389                 ;
390                 ; The fall through to commit_vk to commit any final
391                 ; VKernel being read
392                 ;
394 ; commit_vk: Store the current VKernelBuf into buffer segment
396 commit_vk:
397                 cmp byte [VKernel],0
398                 jz .nolabel                     ; Nothing to commit...
400                 mov di,VKernelBuf+vk_append
401                 add di,[VKernelBuf+vk_appendlen]
403                 ; If we have an initrd statement, append it to the
404                 ; append statement
405                 cmp byte [InitRD+NULLOFFSET],NULLFILE
406                 je .noinitrd
408                 mov si,str_initrd
409                 mov cx,7        ; "initrd="
410                 rep movsb
411                 mov si,InitRD
412                 call strcpy
413                 mov byte [es:di-1],' '
415                 ; For better compression, clean up the append field
416 .noinitrd:
417                 mov ax,di
418                 sub ax,VKernelBuf+vk_append
419                 mov [VKernelBuf+vk_appendlen],ax
420                 mov cx,max_cmd_len+1
421                 sub cx,ax
422                 xor ax,ax
423                 rep stosb
425                 ; Pack into high memory
426                 mov esi,VKernelBuf
427                 mov edi,[VKernelEnd]
428                 mov ecx,vk_size
429                 pm_call rllpack
430                 mov [VKernelEnd],edi
431 .nolabel:
432                 ret
433 .overflow:
434                 mov si,vk_overflow_msg
435                 call writestr
436                 ret
438                 section .data16
439 vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0
440 SerialNotice    db 1                    ; Only print this once
442                 section .bss16
443                 alignb 4
444 VKernelEnd      resd 1                  ; Lowest high memory address used
446                 ; This symbol should be used by loaders to indicate
447                 ; the highest address *they* are allowed to use.
448 HighMemRsvd     equ VKernelEnd
449                                         ; by vkernels
450                 section .config
451                 alignz 4
452 KbdTimeout      dd 0                    ; Keyboard timeout (if any)
453 TotalTimeout    dd 0                    ; Total timeout (if any)
454 AppendLen       dw 0                    ; Bytes in append= command
455 OntimeoutLen    dw 0                    ; Bytes in ontimeout command
456 OnerrorLen      dw 0                    ; Bytes in onerror command
457 CmdLinePtr      dw cmd_line_here        ; Command line advancing pointer
458 ForcePrompt     dw 0                    ; Force prompt
459 NoEscape        dw 0                    ; No escape
460 NoComplete      dw 0                    ; No label completion on TAB key
461 AllowImplicit   dw 1                    ; Allow implicit kernels
462 AllowOptions    dw 1                    ; User-specified options allowed
463 IncludeLevel    dw 1                    ; Nesting level
464 DefaultLevel    dw 0                    ; The current level of default
465                 global PXERetry
466 PXERetry        dw 0                    ; Extra PXE retries
467 VKernel         db 0                    ; Have we seen any "label" statements?
469 %if IS_PXELINUX
470 IPAppend        db 0                    ; Default IPAPPEND option
471 %endif
473                 section .uibss
474                 alignb 4                ; For the good of REP MOVSD
475 command_line    resb max_cmd_len+2      ; Command line buffer
476                 alignb 4
477 default_cmd     resb max_cmd_len+1      ; "default" command line