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; 24pc_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; 35pc_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; 44pc_onerror: mov di,Onerror 45 call getline 46 sub di,Onerror 47 mov [OnerrorLen],di 48 ret 49 50; 51; "append" command 52; 53pc_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 75pc_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; 88pc_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; 98pc_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; 111pc_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; 125pc_totaltimeout: 126 127; 128; Generic integer variable setting commands: 129; "prompt", "implicit" 130; 131pc_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; 143pc_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; 156pc_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; 168pc_include: inc word [IncludeLevel] 169.err: ret 170 171; 172; "serial" command 173; 174pc_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; 285pc_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; 294pc_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; 328pc_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; 335pc_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; 356pc_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; 362pc_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; 372parse_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; 392commit_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 435vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0 436SerialNotice db 1 ; Only print this once 437 438 section .bss16 439 alignb 4 440VKernelEnd 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. 444HighMemRsvd equ VKernelEnd 445 ; by vkernels 446 section .config 447 alignz 4 448KbdTimeout dd 0 ; Keyboard timeout (if any) 449TotalTimeout dd 0 ; Total timeout (if any) 450AppendLen dw 0 ; Bytes in append= command 451OntimeoutLen dw 0 ; Bytes in ontimeout command 452OnerrorLen dw 0 ; Bytes in onerror command 453CmdLinePtr dw cmd_line_here ; Command line advancing pointer 454ForcePrompt dw 0 ; Force prompt 455NoEscape dw 0 ; No escape 456NoComplete dw 0 ; No label completion on TAB key 457AllowImplicit dw 1 ; Allow implicit kernels 458AllowOptions dw 1 ; User-specified options allowed 459IncludeLevel dw 1 ; Nesting level 460DefaultLevel dw 0 ; The current level of default 461 global PXERetry 462PXERetry dw 0 ; Extra PXE retries 463VKernel db 0 ; Have we seen any "label" statements? 464 465%if IS_PXELINUX 466IPAppend db 0 ; Default IPAPPEND option 467%endif 468 469 section .uibss 470 alignb 4 ; For the good of REP MOVSD 471command_line resb max_cmd_len+2 ; Command line buffer 472 alignb 4 473default_cmd resb max_cmd_len+1 ; "default" command line 474

