realloc(): better implementation allowing in-place growth
[syslinux.git] / parseconfig.inc
blob90c1f3c9c2caadd2ac72c9644f81181a659edc68
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4 ;;
5 ;;   This program is free software; you can redistribute it and/or modify
6 ;;   it under the terms of the GNU General Public License as published by
7 ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;;   (at your option) any later version; incorporated herein by reference.
11 ;; -----------------------------------------------------------------------
14 ;; parseconfig.inc
16 ;; Configuration file operations
19                 section .text
21 ; "default" command
23 pc_default:     mov di,default_cmd
24                 call getline
25                 mov byte [di-1],0               ; null-terminate
26                 ret
29 ; "ontimeout" command
31 pc_ontimeout:   mov di,Ontimeout
32                 call getline
33                 sub di,Ontimeout+1              ; Don't need final space
34                 mov [OntimeoutLen],di
35                 ret
38 ; "onerror" command
40 pc_onerror:     mov di,Onerror
41                 call getline
42                 sub di,Onerror
43                 mov [OnerrorLen],di
44                 ret
47 ; "append" command
49 pc_append:      cmp byte [VKernel],0
50                 ja .vk
51                 mov di,AppendBuf
52                 call getline
53                 sub di,AppendBuf
54 .app1:          mov [AppendLen],di
55                 ret
56 .vk:            mov di,VKernelBuf+vk_append     ; "append" command (vkernel)
57                 call getline
58                 sub di,VKernelBuf+vk_append
59                 cmp di,byte 2
60                 jne .app2
61                 cmp byte [VKernelBuf+vk_append],'-'
62                 jne .app2
63                 xor di,di                       ; If "append -" -> null string
64 .app2:          mov [VKernelBuf+vk_appendlen],di
65                 ret
68 ; "ipappend" command (PXELINUX only)
70 %if IS_PXELINUX
71 pc_ipappend:    call getint
72                 jc .err
73                 cmp byte [VKernel],0
74                 jne .vk
75                 mov [IPAppend],bl
76 .err:           ret
77 .vk:            mov [VKernelBuf+vk_ipappend],bl
78                 ret
79 %endif
82 ; "localboot" command (PXELINUX, ISOLINUX)
84 %if IS_PXELINUX || IS_ISOLINUX
85 pc_localboot:   call getint
86                 cmp byte [VKernel],0            ; ("label" section only)
87                 je .err
88                 mov di,VKernelBuf+vk_rname
89                 xor ax,ax
90                 mov cx,FILENAME_MAX
91                 rep stosb                       ; Null kernel name
92 %if IS_PXELINUX
93                 ; PXELINUX uses the first 4 bytes of vk_rname for the
94                 ; mangled IP address
95                 mov [VKernelBuf+vk_rname+5], bx ; Return type
96 %else
97                 mov [VKernelBuf+vk_rname+1], bx ; Return type
98 %endif
99 .err:           ret
100 %endif
103 ; "kernel", "config", ... command
105 pc_kernel:      cmp byte [VKernel],0
106                 je .err                         ; ("label" section only)
107                 mov [VKernelBuf+vk_type],al
108                 call pc_getline
109                 mov di,VKernelBuf+vk_rname
110                 call mangle_name
111 .err:           ret
114 ; "timeout", "totaltimeout" command
116 ; N.B. 1/10 s ~ 1.D2162AABh clock ticks
118 pc_timeout:     push ax
119                 call getint
120                 pop si
121                 jc .err
122                 mov eax,0D2162AABh
123                 mul ebx                         ; clock ticks per 1/10 s
124                 add ebx,edx
125                 mov [si],ebx
126 .err:           ret
130 ; "totaltimeout" command
132 pc_totaltimeout:
135 ; Generic integer variable setting commands:
136 ; "prompt", "implicit"
138 pc_setint16:
139                 push ax
140                 call getint
141                 pop si
142                 jc .err
143                 mov [si],bx
144 .err:           ret
147 ; Generic file-processing commands:
148 ; "font", "kbdmap",
150 pc_filecmd:     push ax                         ; Function to tailcall
151                 call pc_getline
152                 mov di,MNameBuf
153                 call mangle_name
154                 call searchdir
155                 jnz .ok
156                 pop ax                          ; Drop the successor function
157 .ok:            ret                             ; Tailcall if OK, error return
160 ; Commands that expect the file to be opened on top of the getc stack.
161 ; "display", "include"
163 pc_opencmd:     push ax                         ; Function to tailcall
164                 call pc_getline
165                 mov di,MNameBuf
166                 call mangle_name
167                 call open
168                 jnz .ok
169                 pop ax                          ; Drop the successor function
170 .ok:            ret                             ; Tailcall if OK, error return
173 ; "include" command (invoked from pc_opencmd)
175 pc_include:     inc word [IncludeLevel]
176 .err:           ret
179 ; "serial" command
181 pc_serial:      call getint
182                 jc .err
183                 push bx                         ; Serial port #
184                 call skipspace
185                 jnc .ok
186                 pop bx
187 .err:           ret
188 .ok:
189                 call ungetc
190                 call getint
191                 mov [FlowControl], word 0       ; Default to no flow control
192                 jc .nobaud
193 .valid_baud:
194                 push ebx
195                 call skipspace
196                 jc .no_flow
197                 call ungetc
198                 call getint                     ; Hardware flow control?
199                 jnc .valid_flow
200 .no_flow:
201                 xor bx,bx                       ; Default -> no flow control
202 .valid_flow:
203                 and bh,0Fh                      ; FlowIgnore
204                 shl bh,4
205                 mov [FlowIgnore],bh
206                 mov bh,bl
207                 and bx,0F003h                   ; Valid bits
208                 mov [FlowControl],bx
209                 pop ebx                         ; Baud rate
210                 jmp short .parse_baud
211 .nobaud:
212                 mov ebx,DEFAULT_BAUD            ; No baud rate given
213 .parse_baud:
214                 pop di                          ; Serial port #
215                 cmp ebx,byte 75
216                 jb .err                         ; < 75 baud == bogus
217                 mov eax,BAUD_DIVISOR
218                 cdq
219                 div ebx
220                 mov [BaudDivisor],ax
221                 push ax                         ; Baud rate divisor
222                 cmp di,3
223                 ja .port_is_io                  ; If port > 3 then port is I/O addr
224                 shl di,1
225                 mov di,[di+serial_base]         ; Get the I/O port from the BIOS
226 .port_is_io:
227                 mov [SerialPort],di
229                 ;
230                 ; Begin code to actually set up the serial port
231                 ;
232                 lea dx,[di+3]                   ; DX -> LCR
233                 mov al,83h                      ; Enable DLAB
234                 call slow_out
236                 pop ax                          ; Divisor
237                 mov dx,di                       ; DX -> LS
238                 call slow_out
240                 inc dx                          ; DX -> MS
241                 mov al,ah
242                 call slow_out
244                 mov al,03h                      ; Disable DLAB
245                 inc dx                          ; DX -> LCR
246                 inc dx
247                 call slow_out
249                 in al,dx                        ; Read back LCR (detect missing hw)
250                 cmp al,03h                      ; If nothing here we'll read 00 or FF
251                 jne .serial_port_bad            ; Assume serial port busted
252                 dec dx
253                 dec dx                          ; DX -> IER
254                 xor al,al                       ; IRQ disable
255                 call slow_out
257                 inc dx                          ; DX -> FCR/IIR
258                 mov al,01h
259                 call slow_out                   ; Enable FIFOs if present
260                 in al,dx
261                 cmp al,0C0h                     ; FIFOs enabled and usable?
262                 jae .fifo_ok
263                 xor ax,ax                       ; Disable FIFO if unusable
264                 call slow_out
265 .fifo_ok:
267                 inc dx
268                 inc dx                          ; DX -> MCR
269                 in al,dx
270                 or al,[FlowOutput]              ; Assert bits
271                 call slow_out
273                 ; Show some life
274                 cmp byte [SerialNotice],0
275                 je .notfirst
276                 mov byte [SerialNotice],0
278                 mov si,syslinux_banner
279                 call write_serial_str
280                 mov si,copyright_str
281                 call write_serial_str
282 .notfirst:
283                 ret
285 .serial_port_bad:
286                 mov [SerialPort], word 0
287                 ret
290 ; "F"-key command
292 pc_fkey:        push ax
293                 call pc_getline
294                 pop di
295                 call mangle_name                ; Mangle file name
296                 ret
299 ; "label" command
301 pc_label:       call commit_vk                  ; Commit any current vkernel
302                 mov di,VKernelBuf               ; Erase the vkernelbuf for better compression
303                 mov cx,(vk_size >> 1)
304                 xor ax,ax
305                 rep stosw
306                 call pc_getline
307                 mov di,VKernelBuf+vk_vname
308                 call mangle_name                ; Mangle virtual name
309                 mov byte [VKernel],1            ; We've seen a "label" statement
310                 mov si,VKernelBuf+vk_vname      ; By default, rname == vname
311                 ; mov di,VKernelBuf+vk_rname    ; -- already set
312                 mov cx,FILENAME_MAX
313                 rep movsb
314                 mov si,AppendBuf                ; Default append==global append
315                 mov di,VKernelBuf+vk_append
316                 mov cx,[AppendLen]
317                 mov [VKernelBuf+vk_appendlen],cx
318                 rep movsb
319 %if IS_PXELINUX                                 ; PXELINUX only
320                 mov al,[IPAppend]               ; Default ipappend==global ipappend
321                 mov [VKernelBuf+vk_ipappend],al
322 %endif
323                 ret
326 ; "say" command
328 pc_say:         call pc_getline                 ; "say" command
329                 call writestr
330                 jmp crlf                        ; tailcall
333 ; "text" command; ignore everything until we get an "endtext" line
335 pc_text:        call pc_getline                 ; Ignore rest of line
336 .loop:
337                 call pc_getline
338                 jc .eof
340                 ; Leading spaces are already removed...
341                 lodsd
342                 and eax,0xdfdfdfdf              ; Upper case
343                 cmp eax,'ENDT'
344                 jne .loop
345                 lodsd
346                 and eax,0x00dfdfdf              ; Upper case and mask
347                 cmp eax,'EXT'
348                 jne .loop
349                 ; If we get here we hit ENDTEXT
350 .eof:
351                 ret
354 ; Comment line
356 pc_comment:     ; Fall into pc_getline
359 ; Common subroutine: load line into trackbuf; returns with SI -> trackbuf
360 ; CF is set on EOF.
362 pc_getline:     mov di,trackbuf
363                 push di
364                 call getline
365                 mov byte [di],0                 ; Null-terminate
366                 pop si
367                 ret
370 ; Main loop for configuration file parsing
372 parse_config:
373                 mov di,VKernelBuf               ; Clear VKernelBuf at start
374                 xor ax,ax
375                 mov cx,vk_size
376                 rep stosb
378 .again:
379                 call getcommand                 ; Parse one command
380                 jnc .again                      ; If not EOF...
381                 call close
382                 dec word [IncludeLevel]         ; Still parsing?
383                 jnz .again
385                 ;
386                 ; The fall through to commit_vk to commit any final
387                 ; VKernel being read
388                 ;
390 ; commit_vk: Store the current VKernelBuf into buffer segment
392 commit_vk:
393                 ; For better compression, clean up the append field
394                 mov ax,[VKernelBuf+vk_appendlen]
395                 mov di,VKernelBuf+vk_append
396                 add di,ax
397                 mov cx,max_cmd_len+1
398                 sub cx,ax
399                 xor ax,ax
400                 rep stosb
402                 ; Pack into high memory
403                 mov si,VKernelBuf
404                 mov edi,[VKernelEnd]
405                 mov cx,vk_size
406                 call rllpack
407                 mov [VKernelEnd],edi
408                 ret
409 .overflow:
410                 mov si,vk_overflow_msg
411                 call writestr
412                 ret
414                 section .data
415 vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0
416 SerialNotice    db 1                    ; Only print this once
418                 section .bss
419                 alignb 4
420 VKernelEnd      resd 1                  ; Lowest high memory address used
422                 ; This symbol should be used by loaders to indicate
423                 ; the highest address *they* are allowed to use.
424 HighMemRsvd     equ VKernelEnd
425                                         ; by vkernels
426                 section .config
427                 align 4, db 0
428 KbdTimeout      dd 0                    ; Keyboard timeout (if any)
429 TotalTimeout    dd 0                    ; Total timeout (if any)
430 AppendLen       dw 0                    ; Bytes in append= command
431 OntimeoutLen    dw 0                    ; Bytes in ontimeout command
432 OnerrorLen      dw 0                    ; Bytes in onerror command
433 CmdLinePtr      dw cmd_line_here        ; Command line advancing pointer
434 ForcePrompt     dw 0                    ; Force prompt
435 NoEscape        dw 0                    ; No escape
436 AllowImplicit   dw 1                    ; Allow implicit kernels
437 AllowOptions    dw 1                    ; User-specified options allowed
438 IncludeLevel    dw 1                    ; Nesting level
439 SerialPort      dw 0                    ; Serial port base (or 0 for no serial port)
440 VKernel         db 0                    ; Have we seen any "label" statements?
442 %if IS_PXELINUX
443 IPAppend        db 0                    ; Default IPAPPEND option
444 %endif
446                 section .uibss
447                 alignb 4                ; For the good of REP MOVSD
448 command_line    resb max_cmd_len+2      ; Command line buffer
449                 alignb 4
450 default_cmd     resb max_cmd_len+1      ; "default" command line
452 %include "rllpack.inc"