From: ljsebald <ljs...@us...> - 2023-11-10 01:50:44
|
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 e3529c47c1e35fb3a488285e911d4cfdf06a48c0 (commit) via 87f6ed33867bdbffed93da239592deda3fc30adb (commit) from 9c23016db56a8ca885765c115e8742cae65d0506 (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 e3529c47c1e35fb3a488285e911d4cfdf06a48c0 Author: Ruslan Rostovtsev <sw...@21...> Date: Fri Nov 10 08:49:59 2023 +0700 Added Store Queue locking and define's changes (#344) * Added Store Queue locking and define's changes * Apply suggestions from code review * Fix SQ unlocking for sound streams commit 87f6ed33867bdbffed93da239592deda3fc30adb Author: Paul Cercueil <pa...@cr...> Date: Fri Nov 10 02:43:27 2023 +0100 Rework romdisks (#341) * Rework romdisks - KOS_INIT_ROMDISK() is now useless; it is automatically added to the romdisk.o object file. The macro remains just for compatibility with older source code. - If the INIT_FS_ROMDISK init flag has been specified (it is set by default), the romdisk init/shutdown code will be included. Otherwise, it will be garbage-collected automatically. - The /rd VFS entry will only be created if a romdisk has been built-in. Signed-off-by: Paul Cercueil <pa...@cr...> * Add my garbage-collect changes to CHANGELOG Signed-off-by: Paul Cercueil <pa...@cr...> ----------------------------------------------------------------------- Summary of changes: Makefile.rules | 4 ++- doc/CHANGELOG | 2 ++ include/kos/init.h | 16 +++++---- kernel/Makefile | 4 ++- kernel/arch/dreamcast/exports-naomi.txt | 3 ++ kernel/arch/dreamcast/exports-pristine.txt | 3 ++ kernel/arch/dreamcast/hardware/sq.c | 28 +++++++++++++--- kernel/arch/dreamcast/include/dc/sq.h | 52 +++++++++++++++++++++++++----- kernel/arch/dreamcast/kernel/init.c | 17 +++++++--- kernel/arch/dreamcast/sound/snd_stream.c | 16 +++++---- kernel/romdisk/Makefile | 9 ++++++ kernel/romdisk/romdiskbase.c | 16 +++++++++ 12 files changed, 139 insertions(+), 31 deletions(-) create mode 100644 kernel/romdisk/Makefile create mode 100644 kernel/romdisk/romdiskbase.c diff --git a/Makefile.rules b/Makefile.rules index 37b14ec..e670cda 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -67,5 +67,7 @@ romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d $(KOS_ROMDISK_DIR) -v -x .svn -x .keepme romdisk.o: romdisk.img - $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk.o + $(KOS_BASE)/utils/bin2o/bin2o romdisk.img romdisk romdisk_tmp.o + $(KOS_CC) -o romdisk.o -r romdisk_tmp.o $(KOS_LIB_PATHS) -Wl,--whole-archive -lromdiskbase + rm romdisk_tmp.o endif diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 19d1e75..0ad497b 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -193,6 +193,8 @@ KallistiOS version 2.1.0 ----------------------------------------------- - DC Added vmu functions to check/enable/disable the extra 41 blocks [AB] - *** Added driver for the SH4's Watchdog Timer peripheral [FG] - DC Added Moop powered fast path to sq_cpy, added TapamN pvr related sq functions [AB] +- DC Garbage-collect network stack [PC] +- DC Rework romdisks [PC] KallistiOS version 2.0.0 ----------------------------------------------- - DC Broadband Adapter driver fixes [Megan Potter == MP] diff --git a/include/kos/init.h b/include/kos/init.h index a1c94cf..c229203 100644 --- a/include/kos/init.h +++ b/include/kos/init.h @@ -48,16 +48,19 @@ __BEGIN_DECLS void (*bba_la_init_weak)(void) = ((flags) & INIT_NET) ? bba_la_init : NULL; \ extern void bba_la_shutdown(void); \ void (*bba_la_shutdown_weak)(void) = ((flags) & INIT_NET) ? bba_la_shutdown : NULL; \ + extern int fs_romdisk_init(void); \ + int (*fs_romdisk_init_weak)(void) = ((flags) & INIT_FS_ROMDISK) ? fs_romdisk_init : NULL; \ + extern int fs_romdisk_shutdown(void); \ + int (*fs_romdisk_shutdown_weak)(void) = ((flags) & INIT_FS_ROMDISK) ? fs_romdisk_shutdown : NULL; \ extern int export_init(void); \ int (*export_init_weak)(void) = ((flags) & INIT_EXPORT) ? export_init : NULL /** \brief The init flags. Do not modify this directly! */ extern uint32 __kos_init_flags; -/** \brief Define a romdisk for your program, if you'd like one. - \param rd Pointer to the romdisk image in your code. -*/ -#define KOS_INIT_ROMDISK(rd) void * __kos_romdisk = (rd) +/** \brief Deprecated and not useful anymore. */ +#define KOS_INIT_ROMDISK(rd) \ + static void *__old_romdisk __attribute__((unused)) = (rd) /** \brief Built-in romdisk. Do not modify this directly! */ extern void * __kos_romdisk; @@ -81,9 +84,9 @@ extern void * __kos_romdisk; \see dreamcast_initflags @{ */ -/** \brief Default init flags (IRQs on, preemption enabled). */ +/** \brief Default init flags (IRQs on, preemption enabled, romdisks). */ #define INIT_DEFAULT \ - (INIT_IRQ | INIT_THD_PREEMPT) + (INIT_IRQ | INIT_THD_PREEMPT | INIT_FS_ROMDISK) #define INIT_NONE 0x0000 /**< \brief Don't init optional things */ #define INIT_IRQ 0x0001 /**< \brief Enable IRQs at startup */ @@ -93,6 +96,7 @@ extern void * __kos_romdisk; #define INIT_MALLOCSTATS 0x0008 /**< \brief Enable malloc statistics */ #define INIT_QUIET 0x0010 /**< \brief Disable dbgio */ #define INIT_EXPORT 0x0020 /**< \brief Export kernel symbols */ +#define INIT_FS_ROMDISK 0x0040 /**< \brief Enable support for romdisks */ /** @} */ __END_DECLS diff --git a/kernel/Makefile b/kernel/Makefile index 748e65b..7e1b4eb 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -5,7 +5,7 @@ # OBJS = -SUBDIRS = arch debug fs thread net libc exports +SUBDIRS = arch debug fs thread net libc exports romdisk STUBS = stubs/kernel_export_stubs.o stubs/arch_export_stubs.o # Everything from here up should be plain old C. @@ -13,6 +13,7 @@ KOS_CFLAGS += $(KOS_CSTD) all: subdirs $(STUBS) rm -f $(KOS_BASE)/lib/$(KOS_ARCH)/libkallisti.a + kos-ar rcs $(KOS_BASE)/lib/$(KOS_ARCH)/libromdiskbase.a romdisk/*.o kos-ar rcs $(KOS_BASE)/lib/$(KOS_ARCH)/libkallisti.a build/*.o kos-ar rcs $(KOS_BASE)/lib/$(KOS_ARCH)/libkallisti_exports.a stubs/*.o @@ -27,6 +28,7 @@ include $(KOS_BASE)/Makefile.prefab clean: clean_subdirs rm -f build/*.o rm -f build/libc/*.o + rm -f romdisk/*.o rm -f stubs/*.o stubs/kernel_export_stubs.c stubs/arch_export_stubs.c run: diff --git a/kernel/arch/dreamcast/exports-naomi.txt b/kernel/arch/dreamcast/exports-naomi.txt index 2e90505..7f7a5c3 100644 --- a/kernel/arch/dreamcast/exports-naomi.txt +++ b/kernel/arch/dreamcast/exports-naomi.txt @@ -75,6 +75,7 @@ vmu_pkg_parse # SPU spu_memload +spu_memload_sq spu_memread spu_memset spu_dma_transfer @@ -89,6 +90,8 @@ sq_cpy sq_set sq_set16 sq_set32 +sq_lock +sq_unlock # Sound snd_mem_init diff --git a/kernel/arch/dreamcast/exports-pristine.txt b/kernel/arch/dreamcast/exports-pristine.txt index 9c04303..e655d0f 100644 --- a/kernel/arch/dreamcast/exports-pristine.txt +++ b/kernel/arch/dreamcast/exports-pristine.txt @@ -118,6 +118,7 @@ flashrom_get_region # SPU spu_memload +spu_memload_sq spu_memread spu_memset spu_dma_transfer @@ -132,6 +133,8 @@ sq_cpy sq_set sq_set16 sq_set32 +sq_lock +sq_unlock # Sound snd_mem_init diff --git a/kernel/arch/dreamcast/hardware/sq.c b/kernel/arch/dreamcast/hardware/sq.c index 561ae94..9326509 100644 --- a/kernel/arch/dreamcast/hardware/sq.c +++ b/kernel/arch/dreamcast/hardware/sq.c @@ -4,10 +4,14 @@ Copyright (C) 2001 Andrew Kieschnick Copyright (C) 2023 Falco Girgis Copyright (C) 2023 Andy Barajas + Copyright (C) 2023 Ruslan Rostovtsev */ +#include <arch/cache.h> #include <dc/sq.h> #include <kos/dbglog.h> +#include <kos/mutex.h> + /* Functions to clear, copy, and set memory using the sh4 store queues @@ -15,6 +19,16 @@ Based on code by Marcus Comstedt, TapamN, and Moop */ +static mutex_t sq_mutex = MUTEX_INITIALIZER; + +void sq_lock(void) { + mutex_lock(&sq_mutex); +} + +void sq_unlock(void) { + mutex_unlock(&sq_mutex); +} + /* Copies n bytes from src to dest, dest must be 32-byte aligned */ void * sq_cpy(void *dest, const void *src, size_t n) { uint32_t *d = SQ_MASK_DEST(dest); @@ -25,8 +39,10 @@ void * sq_cpy(void *dest, const void *src, size_t n) { _Complex float ds3; _Complex float ds4; + sq_lock(); + /* Set store queue memory area as desired */ - SET_QACR_REGS(dest); + SET_QACR_REGS(dest, dest); /* Fill/write queues as many times necessary */ n >>= 5; @@ -45,8 +61,8 @@ void * sq_cpy(void *dest, const void *src, size_t n) { d[7] = *(s++); /* Fire off store queue. __builtin would move it to the top so - use __asm__ instead */ - __asm__("pref @%0" : : "r"(d)); + use dcache_pref_block instead */ + dcache_pref_block(d); d += 8; } } else { /* If src is 8-byte aligned, fast path */ @@ -85,6 +101,7 @@ void * sq_cpy(void *dest, const void *src, size_t n) { d = (uint32_t *)MEM_AREA_SQ_BASE; d[0] = d[8] = 0; + sq_unlock(); return dest; } @@ -110,8 +127,10 @@ void * sq_set16(void *dest, uint32_t c, size_t n) { void * sq_set32(void *dest, uint32_t c, size_t n) { uint32_t *d = SQ_MASK_DEST(dest); + sq_lock(); + /* Set store queue memory area as desired */ - SET_QACR_REGS(dest); + SET_QACR_REGS(dest, dest); /* Fill both store queues with c */ d[0] = d[1] = d[2] = d[3] = d[4] = d[5] = d[6] = d[7] = @@ -129,6 +148,7 @@ void * sq_set32(void *dest, uint32_t c, size_t n) { d = (uint32_t *)MEM_AREA_SQ_BASE; d[0] = d[8] = 0; + sq_unlock(); return dest; } diff --git a/kernel/arch/dreamcast/include/dc/sq.h b/kernel/arch/dreamcast/include/dc/sq.h index 5dbad30..62c9cd0 100644 --- a/kernel/arch/dreamcast/include/dc/sq.h +++ b/kernel/arch/dreamcast/include/dc/sq.h @@ -4,6 +4,7 @@ Copyright (C) 2000-2001 Andrew Kieschnick Copyright (C) 2023 Falco Girgis Copyright (C) 2023 Andy Barajas + Copyright (C) 2023 Ruslan Rostovtsev */ /** \file dc/sq.h @@ -53,20 +54,55 @@ __BEGIN_DECLS /** \brief Set Store Queue QACR* registers \ingroup store_queues */ -#define SET_QACR_REGS(dest) \ +#define SET_QACR_REGS(dest0, dest1) \ do { \ - uint32_t val = ((uint32_t)(dest)) >> 24; \ - QACR0 = val; \ - QACR1 = val; \ + QACR0 = ((uintptr_t)(dest0)) >> 24; \ + QACR1 = ((uintptr_t)(dest1)) >> 24; \ } while(0) -/** \brief Mask dest to Store Queue area +/** \brief Mask dest to Store Queue area as address + \ingroup store_queues +*/ +#define SQ_MASK_DEST_ADDR(dest) \ + (MEM_AREA_SQ_BASE | ((uintptr_t)(dest) & 0x03ffffe0)) + +/** \brief Mask dest to Store Queue area as pointer \ingroup store_queues */ #define SQ_MASK_DEST(dest) \ - ((uint32_t *)(void *) \ - (MEM_AREA_SQ_BASE | \ - (((uint32_t)(dest)) & 0x03ffffe0))) + ((uint32_t *)(void *) SQ_MASK_DEST_ADDR(dest)) + +/** \brief Lock Store Queues + \ingroup store_queues + + Locks the store queues so that they cannot be used from another thread + until unlocked. + + \warning + This function is called automatically by the store queue API provided by KOS; + however, it must be called manually when driving the SQs directly from outside + of this API. + + \sa sq_unlock() +*/ +void sq_lock(void); + +/** \brief Unlock Store Queues + \ingroup store_queues + + Unlocks the store queues so that they can be used from any thread. + + \note + sq_lock() should've already been called previously. + + \warning + sq_lock() and sq_unlock() are called automatically by the store queue API provided + by KOS; however, they must be called manually when driving the SQs directly from + outside this API. + + \sa sq_lock() +*/ +void sq_unlock(void); /** \brief Copy a block of memory. \ingroup store_queues diff --git a/kernel/arch/dreamcast/kernel/init.c b/kernel/arch/dreamcast/kernel/init.c index 641fd05..11dbd0c 100644 --- a/kernel/arch/dreamcast/kernel/init.c +++ b/kernel/arch/dreamcast/kernel/init.c @@ -89,6 +89,10 @@ void arch_init_net(void) { void (*init_net_weak)(void) __attribute__((weak)); void (*net_shutdown_weak)(void) __attribute__((weak)); +int (*fs_romdisk_init_weak)(void) __attribute__((weak)); +int (*fs_romdisk_shutdown_weak)(void) __attribute__((weak)); +int (*fs_romdisk_mount_weak)(void) __attribute__((weak)); + /* Auto-init stuff: override with a non-weak symbol if you don't want all of this to be linked into your code (and do the same with the arch_auto_shutdown function too). */ @@ -141,7 +145,10 @@ int __attribute__((weak)) arch_auto_init(void) { fs_init(); /* VFS */ fs_pty_init(); /* Pty */ fs_ramdisk_init(); /* Ramdisk */ - fs_romdisk_init(); /* Romdisk */ + + if(fs_romdisk_init_weak) { + fs_romdisk_init_weak(); /* Romdisk */ + } /* The arc4random_buf() function used for random & urandom is only available in newlib starting with version 2.4.0 */ @@ -153,8 +160,8 @@ int __attribute__((weak)) arch_auto_init(void) { hardware_periph_init(); /* DC peripheral init */ - if(__kos_romdisk != NULL) { - fs_romdisk_mount("/rd", __kos_romdisk, 0); + if(fs_romdisk_mount_weak) { + fs_romdisk_mount_weak(); } #ifndef _arch_sub_naomi @@ -210,7 +217,9 @@ void __attribute__((weak)) arch_auto_shutdown(void) { fs_dev_shutdown(); #endif fs_ramdisk_shutdown(); - fs_romdisk_shutdown(); + if(fs_romdisk_shutdown_weak) { + fs_romdisk_shutdown_weak(); + } fs_pty_shutdown(); fs_shutdown(); thd_shutdown(); diff --git a/kernel/arch/dreamcast/sound/snd_stream.c b/kernel/arch/dreamcast/sound/snd_stream.c index 1b5c83c..fcbc9c2 100644 --- a/kernel/arch/dreamcast/sound/snd_stream.c +++ b/kernel/arch/dreamcast/sound/snd_stream.c @@ -200,28 +200,30 @@ static void sep_data(void *buffer, int len, int stereo) { void snd_pcm16_split_sq(uint32_t *data, uintptr_t left, uintptr_t right, size_t size) { + /* SPU memory in cached area */ left |= 0x00800000; right |= 0x00800000; - uint32 masked_left = (0xe0000000 | (left & 0x03ffffe0)); - uint32 masked_right = (0xe0000000 | (right & 0x03ffffe0)); + uintptr_t masked_left = SQ_MASK_DEST_ADDR(left); + uintptr_t masked_right = SQ_MASK_DEST_ADDR(right); + + sq_lock(); /* Set store queue memory area as desired */ - QACR0 = (left >> 24) & 0x1c; - QACR1 = (right >> 24) & 0x1c; + SET_QACR_REGS(left, right); int old = irq_disable(); - do { } while(*(vuint32 *)0xa05f688c & (1 << 5)) ; // FIFO_SH4 - do { } while(*(vuint32 *)0xa05f688c & (1 << 4)) ; // FIFO_G2 + do { } while(*(vuint32 *)0xa05f688c & ((1 << 5) | (1 << 4))); /* FIFO_SH4 | FIFO_G2 */ /* Separating channels and do fill/write queues as many times necessary. */ snd_pcm16_split_sq_start(data, masked_left, masked_right, size); /* Wait for both store queues to complete if they are already used */ - uint32 *d = (uint32 *)0xe0000000; + uint32_t *d = (uint32_t *)MEM_AREA_SQ_BASE; d[0] = d[8] = 0; irq_restore(old); + sq_unlock(); } static void snd_stream_prefill_part(snd_stream_hnd_t hnd, uint32_t offset) { diff --git a/kernel/romdisk/Makefile b/kernel/romdisk/Makefile new file mode 100644 index 0000000..39d44e9 --- /dev/null +++ b/kernel/romdisk/Makefile @@ -0,0 +1,9 @@ +# KallistiOS ##version## +# +# romdisk/Makefile +# (c)2023 Paul Cercueil +# + +OBJS = romdiskbase.o + +include $(KOS_BASE)/Makefile.prefab diff --git a/kernel/romdisk/romdiskbase.c b/kernel/romdisk/romdiskbase.c new file mode 100644 index 0000000..41415d3 --- /dev/null +++ b/kernel/romdisk/romdiskbase.c @@ -0,0 +1,16 @@ +/* KallistiOS ##version## + + kernel/romdisk/romdiskbase.c + Copyright (C) 2023 Paul Cercueil +*/ + +#include <kos/fs_romdisk.h> + +extern unsigned char romdisk[]; + +void *__kos_romdisk = romdisk; + +int fs_romdisk_mount_weak(void) +{ + return fs_romdisk_mount("/rd", __kos_romdisk, 0); +} hooks/post-receive -- A pseudo Operating System for the Dreamcast. |