From: ljsebald <ljs...@us...> - 2023-11-22 05:00:57
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via c37b8e2ac30db217eb1c217f6b1f314d19dcd3e2 (commit) via 88a3a8e06481fe22ffc4653845001e73fd7092f3 (commit) via 6d706e1d5e54a2cc092c0d64b2dd4f842715ae89 (commit) via a246cbfe5f2756e526da17f3d67c2910a4765cf7 (commit) via e228fd47a82d7ff2dbed7c04607069562a40cce6 (commit) from 92a76c016c9d0c89e5f8613189ca6ba7bff1616e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c37b8e2ac30db217eb1c217f6b1f314d19dcd3e2 Merge: 88a3a8e a246cbf Author: Lawrence Sebald <ljs...@us...> Date: Wed Nov 22 00:00:21 2023 -0500 Merge pull request #377 from DC-SWAT/gd_init Fixed GD-ROM init for BIOS mod without CD inserted. commit 88a3a8e06481fe22ffc4653845001e73fd7092f3 Merge: 92a76c0 6d706e1 Author: Lawrence Sebald <ljs...@us...> Date: Tue Nov 21 22:26:18 2023 -0500 Merge pull request #376 from sizious/elf2bin `elf2bin`: adding script to the `utils` directory commit 6d706e1d5e54a2cc092c0d64b2dd4f842715ae89 Author: SiZiOUS <si...@gm...> Date: Tue Nov 21 21:51:51 2023 +0100 `elf2bin`: Removing unnecessary `strip` step commit a246cbfe5f2756e526da17f3d67c2910a4765cf7 Author: DC-SWAT <sw...@21...> Date: Mon Nov 20 12:57:39 2023 +0700 Fixed GD-ROM init for BIOS mod without CD inserted. Also added cdrom_exec_cmd_timed, fixed cdrom_get_status and some cleanup. commit e228fd47a82d7ff2dbed7c04607069562a40cce6 Author: SiZiOUS <si...@gm...> Date: Sun Nov 19 18:43:41 2023 +0100 `elf2bin`: adding script to the `utils` directory This is basically a simple script using `strip` and `kos-objcopy`; basically this makes the conversion "explicit". ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/hardware/cdrom.c | 129 ++++++++++++++++++------------- kernel/arch/dreamcast/include/dc/cdrom.h | 20 ++++- utils/elf2bin/elf2bin | 57 ++++++++++++++ 3 files changed, 149 insertions(+), 57 deletions(-) create mode 100644 utils/elf2bin/elf2bin diff --git a/kernel/arch/dreamcast/hardware/cdrom.c b/kernel/arch/dreamcast/hardware/cdrom.c index 870c5fe..d287503 100644 --- a/kernel/arch/dreamcast/hardware/cdrom.c +++ b/kernel/arch/dreamcast/hardware/cdrom.c @@ -10,11 +10,15 @@ */ #include <assert.h> +#include <arch/timer.h> +#include <arch/memory.h> + #include <dc/cdrom.h> #include <dc/g1ata.h> #include <kos/thread.h> #include <kos/mutex.h> +#include <kos/dbglog.h> /* @@ -49,23 +53,25 @@ hiccups (by severely reducing the number of gd commands being sent). which syscall we want. */ #define MAKE_SYSCALL(rs, p1, p2, idx) \ - uint32 *syscall_bc = (uint32*)0x8c0000bc; \ + uint32_t *syscall_bc = (uint32_t *)(0x0c0000bc | MEM_AREA_P1_BASE); \ int (*syscall)() = (int (*)())(*syscall_bc); \ rs syscall((p1), (p2), 0, (idx)); +typedef int gdc_cmd_hnd_t; + /* Reset system functions */ static void gdc_init_system(void) { MAKE_SYSCALL(/**/, 0, 0, 3); } /* Submit a command to the system */ -static int gdc_req_cmd(int cmd, void *param) { +static gdc_cmd_hnd_t gdc_req_cmd(int cmd, void *param) { MAKE_SYSCALL(return, cmd, param, 0); } /* Check status on an executed command */ -static int gdc_get_cmd_stat(int f, void *status) { - MAKE_SYSCALL(return, f, status, 1); +static int gdc_get_cmd_stat(gdc_cmd_hnd_t hnd, void *status) { + MAKE_SYSCALL(return, hnd, status, 1); } /* Execute submitted commands */ @@ -84,28 +90,28 @@ static int gdc_change_data_type(void *param) { } /* Abort the current command */ -static void gdc_abort_cmd(int cmd) { - MAKE_SYSCALL(/**/, cmd, 0, 8); +static void gdc_abort_cmd(gdc_cmd_hnd_t hnd) { + MAKE_SYSCALL(/**/, hnd, 0, 8); } -#if 0 /* Not used yet */ + /* Reset the GD-ROM syscalls */ static void gdc_reset(void) { MAKE_SYSCALL(/**/, 0, 0, 9); } - +#if 0 /* Not used yet */ /* DMA end interrupt handler */ static void gdc_dma_end(uintptr_t callback, void *param) { MAKE_SYSCALL(/**/, callback, param, 5); } /* Request DMA transfer for DMAREAD_STREAM commands */ -static int gdc_req_dma_transfer(int f, int *params) { - MAKE_SYSCALL(return, f, params, 6); +static int gdc_req_dma_transfer(gdc_cmd_hnd_t hnd, int *params) { + MAKE_SYSCALL(return, hnd, params, 6); } /* Check DMA transfer for DMAREAD_STREAM commands */ -static int gdc_check_dma_transfer(int f, int *size) { - MAKE_SYSCALL(return, f, size, 7); +static int gdc_check_dma_transfer(gdc_cmd_hnd_t hnd, int *size) { + MAKE_SYSCALL(return, hnd, size, 7); } /* Setup PIO transfer end callback for PIOREAD_STREAM commands */ @@ -114,13 +120,13 @@ static void gdc_set_pio_callback(uintptr_t callback, void *param) { } /* Request PIO transfer for PIOREAD_STREAM commands */ -static int gdc_req_pio_transfer(int f, int *params) { - MAKE_SYSCALL(return, f, params, 12); +static int gdc_req_pio_transfer(gdc_cmd_hnd_t hnd, int *params) { + MAKE_SYSCALL(return, hnd, params, 12); } /* Check PIO transfer for PIOREAD_STREAM commands */ -static int gdc_check_pio_transfer(int f, int *size) { - MAKE_SYSCALL(return, f, size, 13); +static int gdc_check_pio_transfer(gdc_cmd_hnd_t hnd, int *size) { + MAKE_SYSCALL(return, hnd, size, 13); } #endif @@ -133,48 +139,67 @@ int cdrom_set_sector_size(int size) { } /* Command execution sequence */ -/* XXX: It might make sense to have a version of this that takes a timeout. */ int cdrom_exec_cmd(int cmd, void *param) { + return cdrom_exec_cmd_timed(cmd, param, 0); +} + +int cdrom_exec_cmd_timed(int cmd, void *param, int timeout) { int status[4] = { 0, /* Error code 1 */ 0, /* Error code 2 */ 0, /* Transfered size */ 0 /* ATA status waiting */ }; - int f, n; + gdc_cmd_hnd_t hnd; + int n, rv = ERR_OK; + uint64_t begin; assert(cmd > 0 && cmd < CMD_MAX); mutex_lock(&_g1_ata_mutex); /* Submit the command */ for(n = 0; n < 10; ++n) { - f = gdc_req_cmd(cmd, param); - if (f > 0) { + hnd = gdc_req_cmd(cmd, param); + if (hnd != 0) { break; } gdc_exec_server(); thd_pass(); } - if(f <= 0) { + if(hnd <= 0) { mutex_unlock(&_g1_ata_mutex); return ERR_SYS; } /* Wait command to finish */ + if(timeout) { + begin = timer_ms_gettime64(); + } do { gdc_exec_server(); - n = gdc_get_cmd_stat(f, status); + n = gdc_get_cmd_stat(hnd, status); if(n != PROCESSING && n != BUSY) { break; } + if(timeout) { + if((timer_ms_gettime64() - begin) >= (unsigned)timeout) { + gdc_abort_cmd(hnd); + gdc_exec_server(); + rv = ERR_TIMEOUT; + dbglog(DBG_ERROR, "cdrom_exec_cmd_timed: Timeout exceeded\n"); + break; + } + } thd_pass(); } while(1); mutex_unlock(&_g1_ata_mutex); - if(n == COMPLETED || n == STREAMING) + if(rv != ERR_OK) + return rv; + else if(n == COMPLETED || n == STREAMING) return ERR_OK; else if(n == NO_ACTIVE) return ERR_NO_ACTIVE; @@ -209,7 +234,15 @@ int cdrom_get_status(int *status, int *disc_type) { mutex_lock(&_g1_ata_mutex); } - rv = gdc_get_drv_stat(params); + do { + rv = gdc_get_drv_stat(params); + + if(rv != BUSY) { + break; + } + thd_pass(); + } while(1); + mutex_unlock(&_g1_ata_mutex); if(rv >= 0) { @@ -282,32 +315,10 @@ int cdrom_reinit(void) { /* Enhanced cdrom_reinit, takes the place of the old 'sector_size' function */ int cdrom_reinit_ex(int sector_part, int cdxa, int sector_size) { - int r = -1; - int timeout; - - /* Try a few times; it might be busy. If it's still busy - after this loop then it's probably really dead. */ - timeout = 10 * 1000 / 20; /* 10 second timeout */ - - while(timeout > 0) { - r = cdrom_exec_cmd(CMD_INIT, NULL); - - if(r == 0) break; - - if(r == ERR_NO_DISC || r == ERR_SYS) { - return r; - } + int r; + r = cdrom_exec_cmd_timed(CMD_INIT, NULL, 10000); - /* Still trying.. sleep a bit and check again */ - thd_sleep(20); - timeout--; - } - - if(timeout <= 0) { - mutex_lock(&_g1_ata_mutex); - /* Send an abort since we're giving up waiting for the init */ - gdc_abort_cmd(CMD_INIT); - mutex_unlock(&_g1_ata_mutex); + if(r == ERR_NO_DISC || r == ERR_SYS || r == ERR_TIMEOUT) { return r; } @@ -457,9 +468,10 @@ int cdrom_spin_down(void) { /* Initialize: assume no threading issues */ int cdrom_init(void) { - uint32 p; - volatile uint32 *react = (uint32 *)0xa05f74e4, - *bios = (uint32 *)0xa0000000; + int status, disc_type; + uint32_t p; + volatile uint32_t *react = (uint32_t *)(0x005f74e4 | MEM_AREA_P2_BASE); + volatile uint32_t *bios = (uint32_t *)MEM_AREA_P2_BASE; mutex_lock(&_g1_ata_mutex); @@ -469,7 +481,7 @@ int cdrom_init(void) { hardware is fitted with custom BIOS using magic bootstrap which can and must pass controller verification with only the first 1024 bytes */ - if((*(uint16 *)0xa0000000) == 0xe6ff) { + if((*(uint16_t *)MEM_AREA_P2_BASE) == 0xe6ff) { *react = 0x3ff; for(p = 0; p < 0x400 / sizeof(bios[0]); p++) { (void)bios[p]; @@ -482,11 +494,18 @@ int cdrom_init(void) { } /* Reset system functions */ + gdc_reset(); gdc_init_system(); mutex_unlock(&_g1_ata_mutex); - /* Do an initial initialization */ - cdrom_reinit(); + cdrom_get_status(&status, &disc_type); + + if(status < CD_STATUS_OPEN && disc_type > CD_CDDA && disc_type < CD_FAIL) { + /* Do an initial initialization */ + cdrom_reinit(); + } else { + dbglog(DBG_INFO, "cdrom_init: No disc inserted\n"); + } return 0; } diff --git a/kernel/arch/dreamcast/include/dc/cdrom.h b/kernel/arch/dreamcast/include/dc/cdrom.h index 8bf16b4..b50d1ce 100644 --- a/kernel/arch/dreamcast/include/dc/cdrom.h +++ b/kernel/arch/dreamcast/include/dc/cdrom.h @@ -83,6 +83,7 @@ __BEGIN_DECLS #define ERR_SYS 3 /**< \brief System error */ #define ERR_ABORTED 4 /**< \brief Command aborted */ #define ERR_NO_ACTIVE 5 /**< \brief System inactive? */ +#define ERR_TIMEOUT 6 /**< \brief Aborted due to timeout */ /** @} */ /** \defgroup cd_cmd_status CD-ROM Command Status responses @@ -182,6 +183,7 @@ __BEGIN_DECLS #define CD_STATUS_NO_DISC 7 /**< \brief No disc inserted */ #define CD_STATUS_RETRY 8 /**< \brief Retry is needed */ #define CD_STATUS_ERROR 9 /**< \brief System error */ +#define CD_STATUS_FATAL 12 /**< \brief Need reset syscalls */ /** @} */ /** \defgroup cd_disc_types CD-ROM drive disc types @@ -190,11 +192,12 @@ __BEGIN_DECLS the cdrom_get_status() function. @{ */ -#define CD_CDDA 0 /**< \brief Audio CD (Red book) */ +#define CD_CDDA 0x00 /**< \brief Audio CD (Red book) or no disc */ #define CD_CDROM 0x10 /**< \brief CD-ROM or CD-R (Yellow book) */ #define CD_CDROM_XA 0x20 /**< \brief CD-ROM XA (Yellow book extension) */ #define CD_CDI 0x30 /**< \brief CD-i (Green book) */ #define CD_GDROM 0x80 /**< \brief GD-ROM */ +#define CD_FAIL 0xf0 /**< \brief Need reset syscalls */ /** @} */ /** \brief TOC structure returned by the BIOS. @@ -255,7 +258,7 @@ int cdrom_set_sector_size(int size); /** \brief Execute a CD-ROM command. This function executes the specified command using the BIOS syscall for - executing GD-ROM commands. This is now thread-safe to be called by users. + executing GD-ROM commands. \param cmd The command number to execute. \param param Data to pass to the syscall. @@ -264,6 +267,19 @@ int cdrom_set_sector_size(int size); */ int cdrom_exec_cmd(int cmd, void *param); +/** \brief Execute a CD-ROM command with timeout. + + This function executes the specified command using the BIOS syscall for + executing GD-ROM commands with timeout. + + \param cmd The command number to execute. + \param param Data to pass to the syscall. + \param timeout Timeout in milliseconds. + + \return \ref cd_cmd_response +*/ +int cdrom_exec_cmd_timed(int cmd, void *param, int timeout); + /** \brief Get the status of the GD-ROM drive. \param status Space to return the drive's status. diff --git a/utils/elf2bin/elf2bin b/utils/elf2bin/elf2bin new file mode 100644 index 0000000..b4ffbfa --- /dev/null +++ b/utils/elf2bin/elf2bin @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# elf2bin +# script to convert an elf program to a bin(ary) program +# then you can use 'scramble' to generate a '1ST_READ.BIN' file +# this script is basically using 'strip' and 'objcopy'. + +me=`basename "$0"` + +# Retrieve args +source=$1 +destination=$2 + +# Check if we want to overwrite (force) the destination file +force_switch=$3 +if [ "$destination" = "-f" ] || [ "$force_switch" = "-f" ]; then + force_switch=1 + unset destination +else + force_switch=0 +fi + +# Check for args +if [ -z "$source" ]; then + echo "usage: $me <binary.elf> [binary.bin] [-f]"; + exit 1 +fi + +# Check for source file existence +if [ ! -f "$source" ]; then + echo "$me: error: file not found: $source"; + exit 2 +fi + +# Compute destination file if destination arg is not passed +if [ -z "$destination" ]; then + destination="${source%.*}.bin" +fi + +# Check if destination file exists (or ignore if requested) +if [ -f "$destination" ] && [ "$force_switch" = "0" ]; then + echo "$me: error: file already exists: $destination"; + exit 3 +fi + +# Compute a temporary filename used to work on the elf file +workdir=$(mktemp -d) +tmpfile="$workdir/$(basename $0).$$.tmp" + +# Do the conversion +cp "$source" "$tmpfile" +kos-objcopy -O binary "$tmpfile" "$destination" + +# Remove the temporary directory +if [ -d "$workdir" ]; then + rm -r "$workdir" +fi hooks/post-receive -- A pseudo Operating System for the Dreamcast. |