Add logo by Abi Rasheed
[profile/ivi/syslinux.git] / core / parseconfig.inc
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.
11 ;;
12 ;; -----------------------------------------------------------------------
13
14 ;;
15 ;; parseconfig.inc
16 ;;
17 ;; Configuration file operations
18 ;;
19
20                 section .text16
21 ;
22 ; "default" or "ui" command, with level (1 = default, 2 = ui)
23 ;
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
31
32 ;
33 ; "ontimeout" command
34 ;
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
40
41 ;
42 ; "onerror" command
43 ;
44 pc_onerror:     mov di,Onerror
45                 call getline
46                 sub di,Onerror
47                 mov [OnerrorLen],di
48                 ret
49
50 ;
51 ; "append" command
52 ;
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
70
71 ;
72 ; "ipappend" command (PXELINUX only)
73 ;
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
84
85 ;
86 ; "localboot" command
87 ;
88 pc_localboot:   call getint
89                 cmp byte [VKernel],0            ; ("label" section only)
90                 je .err
91                 mov [VKernelBuf+vk_rname],bx
92                 mov byte [VKernelBuf+vk_type],VK_LOCALBOOT
93 .err:           ret
94
95 ;
96 ; "kernel", "config", ... command
97 ;
98 pc_kernel:      cmp byte [VKernel],0
99                 je .err                         ; ("label" section only)
100                 mov [VKernelBuf+vk_type],al
101                 call pc_getline
102                 mov di,VKernelBuf+vk_rname
103                 pm_call pm_mangle_name
104 .err:           ret
105
106 ;
107 ; "timeout", "totaltimeout" command
108 ;
109 ; N.B. 1/10 s ~ 1.D2162AABh clock ticks
110 ;
111 pc_timeout:     push ax
112                 call getint
113                 pop si
114                 jc .err
115                 mov eax,0D2162AABh
116                 mul ebx                         ; clock ticks per 1/10 s
117                 add ebx,edx
118                 mov [si],ebx
119 .err:           ret
120
121
122 ;
123 ; "totaltimeout" command
124 ;
125 pc_totaltimeout:
126
127 ;
128 ; Generic integer variable setting commands:
129 ; "prompt", "implicit"
130 ;
131 pc_setint16:
132                 push ax
133                 call getint
134                 pop si
135                 jc .err
136                 mov [si],bx
137 .err:           ret
138
139 ;
140 ; Generic file-processing commands:
141 ; "font", "kbdmap",
142 ;
143 pc_filecmd:     push ax                         ; Function to tailcall
144                 call pc_getline
145                 mov di,MNameBuf
146                 pm_call pm_mangle_name
147                 pm_call pm_searchdir
148                 jnz .ok
149                 pop ax                          ; Drop the successor function
150 .ok:            ret                             ; Tailcall if OK, error return
151
152 ;
153 ; Commands that expect the file to be opened on top of the getc stack.
154 ; "display", "include"
155 ;
156 pc_opencmd:     push ax                         ; Function to tailcall
157                 call pc_getline
158                 mov di,MNameBuf
159                 pm_call pm_mangle_name
160                 call core_open
161                 jnz .ok
162                 pop ax                          ; Drop the successor function
163 .ok:            ret                             ; Tailcall if OK, error return
164
165 ;
166 ; "include" command (invoked from pc_opencmd)
167 ;
168 pc_include:     inc word [IncludeLevel]
169 .err:           ret
170
171 ;
172 ; "serial" command
173 ;
174 pc_serial:      call getint
175                 jc .err
176                 push bx                         ; Serial port #
177                 xor eax,eax
178                 mov [FlowControl],eax           ; Default to no flow control
179                 call skipspace
180                 jc .nobaud
181                 call ungetc
182                 call getint
183                 jc .nobaud
184 .valid_baud:
185                 push ebx
186                 call skipspace
187                 jc .no_flow
188                 call ungetc
189                 call getint                     ; Hardware flow control?
190                 jnc .valid_flow
191 .no_flow:
192                 xor bx,bx                       ; Default -> no flow control
193 .valid_flow:
194                 and bh,0Fh                      ; FlowIgnore
195                 shl bh,4
196                 mov [FlowIgnore],bh
197                 mov bh,bl
198                 and bx,0F00Bh                   ; Valid bits
199                 mov [FlowControl],bx
200                 pop ebx                         ; Baud rate
201                 jmp short .parse_baud
202 .nobaud:
203                 mov ebx,DEFAULT_BAUD            ; No baud rate given
204 .parse_baud:
205                 pop di                          ; Serial port #
206                 cmp ebx,byte 75
207                 jb .err                         ; < 75 baud == bogus
208                 mov eax,BAUD_DIVISOR
209                 cdq
210                 div ebx
211                 mov [BaudDivisor],ax
212                 push ax                         ; Baud rate divisor
213                 cmp di,3
214                 ja .port_is_io                  ; If port > 3 then port is I/O addr
215                 shl di,1
216                 mov di,[di+serial_base]         ; Get the I/O port from the BIOS
217 .port_is_io:
218                 mov [SerialPort],di
219
220                 ;
221                 ; Begin code to actually set up the serial port
222                 ;
223                 call sirq_cleanup_nowipe        ; Cleanup existing IRQ handler
224
225                 lea dx,[di+3]                   ; DX -> LCR
226                 mov al,83h                      ; Enable DLAB
227                 slow_out dx,al
228
229                 pop ax                          ; Divisor
230                 mov dx,di                       ; DX -> LS
231                 slow_out dx,al
232
233                 inc dx                          ; DX -> MS
234                 mov al,ah
235                 slow_out dx,al
236
237                 mov al,03h                      ; Disable DLAB
238                 inc dx                          ; DX -> LCR
239                 inc dx
240                 slow_out dx,al
241
242                 in al,dx                ; Read back LCR (detect missing hw)
243                 cmp al,03h              ; If nothing here we'll read 00 or FF
244                 jne .err                ; Assume serial port busted
245                 dec dx                          ; DX -> IIR/FCR
246                 mov al,01h
247                 slow_out dx,al                  ; Enable FIFOs if present
248                 in al,dx
249                 cmp al,0C0h                     ; FIFOs enabled and usable?
250                 jae .fifo_ok
251                 xor ax,ax                       ; Disable FIFO if unusable
252                 slow_out dx,al
253 .fifo_ok:
254
255                 inc dx
256                 inc dx                          ; DX -> MCR
257                 mov al,[FlowOutput]             ; Assert bits
258                 slow_out dx,al
259
260                 ; Enable interrupts if requested
261                 test al,8
262                 jz .noirq
263                 call sirq_install
264 .noirq:
265
266                 ; Show some life
267                 cmp byte [SerialNotice],0
268                 je .notfirst
269                 mov byte [SerialNotice],0
270
271                 mov si,syslinux_banner
272                 call write_serial_str
273                 mov si,copyright_str
274                 call write_serial_str
275 .notfirst:
276                 ret
277
278 .err:
279                 mov [SerialPort], word 0
280                 ret
281
282 ;
283 ; Store mangled filename command (F-keys, "initrd")
284 ;
285 pc_filename:    push ax
286                 call pc_getline
287                 pop di
288                 pm_call pm_mangle_name          ; Mangle file name
289                 ret
290
291 ;
292 ; "label" command
293 ;
294 pc_label:       call commit_vk                  ; Commit any current vkernel
295                 mov byte [InitRD+NULLOFFSET],NULLFILE   ; No "initrd" statement
296                 mov di,VKernelBuf               ; Erase the vkernelbuf for better compression
297                 mov cx,(vk_size >> 1)
298                 xor ax,ax
299                 rep stosw
300                 call pc_getline
301                 mov di,VKernelBuf+vk_vname
302                 mov cx,FILENAME_MAX-1
303 .loop:
304                 lodsb
305                 cmp al,' '
306                 jna .done
307                 stosb
308                 loop .loop
309 .done:
310                 mov byte [VKernel],1            ; We've seen a "label" statement
311                 mov si,VKernelBuf+vk_vname      ; By default, rname == mangled vname
312                 mov di,VKernelBuf+vk_rname
313                 pm_call pm_mangle_name
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
324
325 ;
326 ; "say" command
327 ;
328 pc_say:         call pc_getline                 ; "say" command
329                 call writestr
330                 jmp crlf                        ; tailcall
331
332 ;
333 ; "text" command; ignore everything until we get an "endtext" line
334 ;
335 pc_text:        call skipline                   ; Ignore rest of line
336 .loop:
337                 call pc_getline
338                 jc .eof
339
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
352
353 ;
354 ; Comment line
355 ;
356 pc_comment:     ; Fall into pc_getline
357
358 ;
359 ; Common subroutine: load line into trackbuf; returns with SI -> trackbuf
360 ; CF is set on EOF.
361 ;
362 pc_getline:     mov di,trackbuf
363                 push di
364                 call getline
365                 mov byte [di],0                 ; Null-terminate
366                 pop si
367                 ret
368
369 ;
370 ; Main loop for configuration file parsing
371 ;
372 parse_config:
373                 mov di,VKernelBuf               ; Clear VKernelBuf at start
374                 xor ax,ax
375                 mov cx,vk_size
376                 rep stosb
377
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
384
385                 ;
386                 ; The fall through to commit_vk to commit any final
387                 ; VKernel being read
388                 ;
389 ;
390 ; commit_vk: Store the current VKernelBuf into buffer segment
391 ;
392 commit_vk:
393                 cmp byte [VKernel],0
394                 jz .nolabel                     ; Nothing to commit...
395
396                 mov di,VKernelBuf+vk_append
397                 add di,[VKernelBuf+vk_appendlen]
398
399                 ; If we have an initrd statement, append it to the
400                 ; append statement
401                 cmp byte [InitRD+NULLOFFSET],NULLFILE
402                 je .noinitrd
403
404                 mov si,str_initrd
405                 mov cx,7        ; "initrd="
406                 rep movsb
407                 mov si,InitRD
408                 call strcpy
409                 mov byte [es:di-1],' '
410
411                 ; For better compression, clean up the append field
412 .noinitrd:
413                 mov ax,di
414                 sub ax,VKernelBuf+vk_append
415                 mov [VKernelBuf+vk_appendlen],ax
416                 mov cx,max_cmd_len+1
417                 sub cx,ax
418                 xor ax,ax
419                 rep stosb
420
421                 ; Pack into high memory
422                 mov esi,VKernelBuf
423                 mov edi,[VKernelEnd]
424                 mov ecx,vk_size
425                 pm_call rllpack
426                 mov [VKernelEnd],edi
427 .nolabel:
428                 ret
429 .overflow:
430                 mov si,vk_overflow_msg
431                 call writestr
432                 ret
433
434                 section .data16
435 vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0
436 SerialNotice    db 1                    ; Only print this once
437
438                 section .bss16
439                 alignb 4
440 VKernelEnd      resd 1                  ; Lowest high memory address used
441
442                 ; This symbol should be used by loaders to indicate
443                 ; the highest address *they* are allowed to use.
444 HighMemRsvd     equ VKernelEnd
445                                         ; by vkernels
446                 section .config
447                 alignz 4
448 KbdTimeout      dd 0                    ; Keyboard timeout (if any)
449 TotalTimeout    dd 0                    ; Total timeout (if any)
450 AppendLen       dw 0                    ; Bytes in append= command
451 OntimeoutLen    dw 0                    ; Bytes in ontimeout command
452 OnerrorLen      dw 0                    ; Bytes in onerror command
453 CmdLinePtr      dw cmd_line_here        ; Command line advancing pointer
454 ForcePrompt     dw 0                    ; Force prompt
455 NoEscape        dw 0                    ; No escape
456 NoComplete      dw 0                    ; No label completion on TAB key
457 AllowImplicit   dw 1                    ; Allow implicit kernels
458 AllowOptions    dw 1                    ; User-specified options allowed
459 IncludeLevel    dw 1                    ; Nesting level
460 DefaultLevel    dw 0                    ; The current level of default
461                 global PXERetry
462 PXERetry        dw 0                    ; Extra PXE retries
463 VKernel         db 0                    ; Have we seen any "label" statements?
464
465 %if IS_PXELINUX
466 IPAppend        db 0                    ; Default IPAPPEND option
467 %endif
468
469                 section .uibss
470                 alignb 4                ; For the good of REP MOVSD
471 command_line    resb max_cmd_len+2      ; Command line buffer
472                 alignb 4
473 default_cmd     resb max_cmd_len+1      ; "default" command line