Skip to content

Commit

Permalink
log: improve logging by impelementing a string formatter
Browse files Browse the repository at this point in the history
The strutils now provides the `strformat` routine that can format a string
with parameters passed on the stack. Thanks to it, we can simplify other components
when it comes to logging messages.
  • Loading branch information
Zeal8bit committed Jun 30, 2024
1 parent af95f76 commit c62cc15
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 131 deletions.
65 changes: 37 additions & 28 deletions include/strutils_h.asm
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
; SPDX-FileCopyrightText: 2023 Zeal 8-bit Computer <[email protected]>
; SPDX-FileCopyrightText: 2023-2024 Zeal 8-bit Computer <[email protected]>
;
; SPDX-License-Identifier: Apache-2.0

IFNDEF STRUTILS_H
DEFINE STRUTILS_H
IFNDEF STRUTILS_H
DEFINE STRUTILS_H

; Public routines. The descriptions are given in the implementation file.
EXTERN strltrim
EXTERN strrtrim
EXTERN strcmp
EXTERN strchrnul
EXTERN strncmp
EXTERN memsep
EXTERN strsep
EXTERN strlen
EXTERN strcpy
EXTERN strcpy_unsaved
EXTERN strncpy
EXTERN strncat
EXTERN strtolower
EXTERN strtoupper
EXTERN parse_int
EXTERN parse_hex
EXTERN parse_dec
EXTERN is_print
EXTERN is_alpha_numeric
EXTERN is_digit
EXTERN to_lower
EXTERN to_upper
EXTERN byte_to_ascii
DEFC FORMAT_SPECIFIER = 0x80
DEFC FORMAT_SPECIFIER_MASK = 0xf

ENDIF ; STRUTILS_H
; Replace with 4 characters (char array)
DEFC FORMAT_4_CHAR = FORMAT_SPECIFIER | 0 | (4 << 4)
DEFC FORMAT_STRING = FORMAT_SPECIFIER | 1
DEFC FORMAT_U8_HEX = FORMAT_SPECIFIER | 2
DEFC FORMAT_CHAR = FORMAT_SPECIFIER | 3

; Public routines. The descriptions are given in the implementation file.
EXTERN strformat
EXTERN strltrim
EXTERN strcmp
EXTERN strchrnul
EXTERN strncmp
EXTERN memsep
EXTERN strsep
EXTERN strlen
EXTERN strcpy
EXTERN strcpy_unsaved
EXTERN strncpy
EXTERN strncat
EXTERN strtolower
EXTERN strtoupper
EXTERN parse_int
EXTERN parse_hex
EXTERN parse_dec
EXTERN is_print
EXTERN is_alpha_numeric
EXTERN is_digit
EXTERN to_lower
EXTERN to_upper
EXTERN byte_to_ascii

ENDIF ; STRUTILS_H
28 changes: 14 additions & 14 deletions kernel/boot.asm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
INCLUDE "target_h.asm"
INCLUDE "log_h.asm"
INCLUDE "vfs_h.asm"
INCLUDE "strutils_h.asm"

; Forward declaration of symbols used below
EXTERN zos_drivers_init
Expand All @@ -22,6 +23,7 @@
EXTERN __KERNEL_BSS_size
EXTERN __DRIVER_BSS_head
EXTERN __DRIVER_BSS_size
EXTERN _vfs_work_buffer

SECTION KERNEL_TEXT

Expand Down Expand Up @@ -86,9 +88,9 @@ zos_entry:
call zos_time_is_available
rrca
jp c, _zos_boot_time_ok
; Print a warning saying that we don't have any time driver
; Print a warning saying that we don't have any timer driver
ld b, a ; BC not altered by log
ld hl, zos_time_warning
ld hl, zos_timer_warning
call zos_log_warning
ld a, b
_zos_boot_time_ok:
Expand All @@ -108,23 +110,21 @@ _zos_boot_date_ok:
ld (boot_ready), a

ld hl, _zos_default_init
; Push on the stack in case of an error, we will need it for
; the formatting string. In case of success, it will be overwritten.
push hl
call zos_load_init_file
; If we return from zos_load_file, an error occurred
ld hl, _load_error_1
ld hl, _load_error
ld de, _vfs_work_buffer
call strformat
ex de, hl
call zos_log_error
xor a
ld hl, _zos_default_init
call zos_log_message
xor a
ld hl, _load_error_2
call zos_log_message
; Loop until the board is rebooted
reboot: halt
jp reboot

_load_error_1: DEFM "Could not load ", 0
_load_error_2: DEFM " initialization file\n", 0

_load_error: DEFM "Could not load ", FORMAT_STRING, " initialization file\n", 0

PUBLIC _zos_default_init
_zos_default_init:
Expand All @@ -136,12 +136,12 @@ _zos_default_init:
zos_boilerplate:
INCBIN "version.txt"
DEFB "\n", 0
zos_time_warning: DEFM "Timer unavailable\n", 0
zos_timer_warning: DEFM "Timer unavailable\n", 0
zos_date_warning: DEFM "Date unavailable\n", 0
zos_kernel_ready:
DEFM "Kernel ready.\nLoading "
CONFIG_KERNEL_INIT_EXECUTABLE
DEFM " @"
DEFM " @"
STR(CONFIG_KERNEL_INIT_EXECUTABLE_ADDR)
DEFM "\n\n", 0

Expand Down
17 changes: 6 additions & 11 deletions kernel/disks.asm
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
EXTERN _vfs_work_buffer
EXTERN boot_ready

DEFC TMP_WORK_BUFFER = _vfs_work_buffer + VFS_WORK_BUFFER_SIZE / 2

PUBLIC zos_disks_init
zos_disks_init:
; Set the default disk to A
Expand Down Expand Up @@ -111,23 +109,20 @@ _zos_disks_mount_already_mounted:
; Alters:
; A, BC, HL
_zos_disk_print_mounter_disk:
push de
; Convert the index to an ASCII letter
ld a, b
add 'A'
; Copy message from ROM to RAM
push de
ld de, TMP_WORK_BUFFER
push af
ld hl, _mounted_msg
ld bc, _mounted_msg_end - _mounted_msg
ldir
; Replace the letter in the message
ld (TMP_WORK_BUFFER + 5), a
ld hl, TMP_WORK_BUFFER
ld de, _vfs_work_buffer
call strformat
ex de, hl
call zos_log_info
pop de
ret
_mounted_msg:
DEFM "Disk ? mounted\n", 0
DEFM "Disk ", FORMAT_CHAR, " mounted\n", 0
_mounted_msg_end:
ENDIF

Expand Down
72 changes: 26 additions & 46 deletions kernel/drivers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,14 @@

PUBLIC zos_drivers_init
zos_drivers_init:
; Initialize the messages, use the global usable buffer
ld hl, _driver_log_success
ld de, _vfs_work_buffer
ld bc, _driver_log_end - _driver_log_success
ldir

; Browse the driver vectors and try to initialize them all
ld hl, __KERNEL_DRV_VECTORS_head
; Load the size of the vectors in B
; Unfortunately, we can't assert on a linker symbol
ld b, __KERNEL_DRV_VECTORS_size / driver_end

_zos_driver_init_next_driver:
push bc
; HL points to the name of the driver
call zos_driver_name_valid ; Check if the name is valid
jp nc, _zos_valid_name
Expand Down Expand Up @@ -63,62 +58,51 @@ _zos_next_driver:
; Skip to the next driver in the list
ld a, driver_end
ADD_HL_A()
pop bc
djnz _zos_driver_init_next_driver
; Log finished registering drivers
ret

_driver_log_success: DEFM "Driver: .... init success\n", 0
_driver_log_failed: DEFM "Driver: .... init error $..\n", 0
_driver_log_success: DEFM "Driver: ", FORMAT_4_CHAR , " init success\n", 0
_driver_log_failed: DEFM "Driver: ", FORMAT_4_CHAR , " init error $", FORMAT_U8_HEX ,"\n", 0
_driver_log_end:

DEFC SUCCESS_MESSAGE_LEN = _driver_log_failed - _driver_log_success
DEFC FAILED_MESSAGE_LEN = _driver_log_end - _driver_log_failed
DEFC LOG_MESSAGES_LEN = FAILED_MESSAGE_LEN + SUCCESS_MESSAGE_LEN
ASSERT(VFS_WORK_BUFFER_SIZE >= SUCCESS_MESSAGE_LEN + FAILED_MESSAGE_LEN)

; Copies the driver name and the error to the log buffer.
; Then calls the error log function.
; Parameters:
; HL - Driver name (4 characters)
; DE - Temporary buffer
; A - Error code
; Alters:
; A, C, DE
_zos_driver_log_error:
; Setting C to DRIVER_NAME_LENGTH will prevent any modification
; on B when performing ldir
ld c, DRIVER_NAME_LENGTH
; HL must not be altered
push hl
; Point to the log failed message
ld de, _vfs_work_buffer + SUCCESS_MESSAGE_LEN + 8
REPT DRIVER_NAME_LENGTH
ldi
ENDR
; Point to failed log message's error code
ld hl, _vfs_work_buffer + LOG_MESSAGES_LEN - 4
call byte_to_ascii
ld (hl), d
inc hl
ld (hl), e
ld hl, _vfs_work_buffer + SUCCESS_MESSAGE_LEN
; Push the error code on the stack for the format string
push af
push hl
; REPT DRIVER_NAME_LENGTH
ld hl, _driver_log_failed
; Prepare the temporary buffer in DE
ld de, _vfs_work_buffer
call strformat
ex de, hl
call zos_log_error
pop hl
ret
; Same as above but with a success
_zos_driver_log_success:
; Setting C to DRIVER_NAME_LENGTH will prevent any modification
; on B when performing ldir
ld c, DRIVER_NAME_LENGTH
; HL must not be altered
push hl
; Point to the log failed message
ld de, _vfs_work_buffer + 8
REPT DRIVER_NAME_LENGTH
ldi
ENDR
ld hl, _vfs_work_buffer
push hl
ld hl, _driver_log_success
ld de, _vfs_work_buffer
call strformat
; Put the message to print in DE, as required by zos_log_info
ex de, hl
call zos_log_info
xor a
pop hl
; Do not alter former flags
or a
ret

; Checks whether the name has already been registered
Expand All @@ -128,7 +112,7 @@ _zos_driver_log_success:
; A - 0 if exists, non-zero else
; DE - Address of the existing drivers (if any)
; Alters:
; A, DE, C
; A, DE, BC
PUBLIC zos_driver_find_by_name
zos_driver_find_by_name:
; If we have no drivers, returns 1 directly
Expand All @@ -152,7 +136,6 @@ zos_driver_find_by_name:
; B must not be altered, but C can be altered
jp zos_disks_get_driver_and_fs
_zos_driver_find_by_name_driver:
push bc
; Save HL as it must not be destroyed
push hl
; Calculate the offset in the loaded drivers array
Expand Down Expand Up @@ -185,7 +168,6 @@ _zos_driver_find_by_name_loop:
inc a ; return A strictly positive
_zos_driver_find_by_name_already_exists:
pop hl
pop bc
ret
_zos_driver_failure:
ld a, ERR_INVALID_NAME
Expand Down Expand Up @@ -233,15 +215,14 @@ zos_driver_name_valid:
; Returns:
; A - 0 on success, error code else
; Alters:
; A, DE
; A, BC, DE
zos_driver_register:
; Check if we can still register a driver
ld a, (_loaded_drivers_count)
cp CONFIG_KERNEL_MAX_LOADED_DRIVERS
jr z, _zos_driver_register_full
; Call the driver's init function first
; Save HL and BC as we need them in the caller
push bc
; Save HL as we need it in the caller
push hl
; Optimize a bit
ASSERT(driver_init_t == 4)
Expand All @@ -257,7 +238,6 @@ zos_driver_register:
; Perform a call to a register address (HL)
CALL_HL()
pop hl
pop bc
; If it succeeded but is hidden, return (but as a success)
ASSERT(ERR_DRIVER_HIDDEN == 255)
inc a
Expand Down
Loading

0 comments on commit c62cc15

Please sign in to comment.