From: ljsebald <ljs...@us...> - 2023-01-03 05:43:20
|
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 233498b60d5707f66e087b82a0e8301a0ee7f5e2 (commit) via 1bebd16a88d2394cb7c24d472f960377b15d9b83 (commit) via f0a8ccb9de3b38c1750d805929d0c45b077fa7a7 (commit) via 0dc764715578f55221b50a8d21fc21f500a4f8fc (commit) via 2f3d13a862cf6be6cb4fbf16d3dd2d000f74b986 (commit) via d8afbad400b25fec0b96ceefc972ee6265ace169 (commit) via 46784aa021e7248ec8ae51b6412e0ae873c50f95 (commit) from dcfc201aee5865b0168944e83ecdc25e67f456d3 (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 233498b60d5707f66e087b82a0e8301a0ee7f5e2 Merge: dcfc201 1bebd16 Author: Lawrence Sebald <ljs...@us...> Date: Mon Jan 2 19:27:52 2023 -0500 Merge pull request #82 from darcagn/32mb-mk4 Support 32MB system RAM configurations commit 1bebd16a88d2394cb7c24d472f960377b15d9b83 Author: darc <da...@pr...> Date: Mon Jan 2 15:12:59 2023 -0600 Cast _arch_mem_top macro to uint32 in 16MB toolchain fallback to eliminate warnings; change #warning to #pragma message to prevent build failures in files using -Werror commit f0a8ccb9de3b38c1750d805929d0c45b077fa7a7 Author: darc <da...@pr...> Date: Mon Jan 2 14:17:24 2023 -0600 Patches for GCC 4.7.4, 9.3.0, and 9.3.0-AppleSilicon: Add custom built-in defines for KOS; patch GCC to set up stack for 32MB memory if available commit 0dc764715578f55221b50a8d21fc21f500a4f8fc Author: darc <da...@pr...> Date: Mon Jan 2 13:36:05 2023 -0600 Add memory testing application as example for utilizing system memory size functions; Tweak 32MB macros in arch.h; Add name to AUTHORS file commit 2f3d13a862cf6be6cb4fbf16d3dd2d000f74b986 Author: darc <da...@pr...> Date: Mon Jan 2 02:42:47 2023 -0600 Updated incorrect function reference in code comment in arch.h commit d8afbad400b25fec0b96ceefc972ee6265ace169 Author: darc <da...@pr...> Date: Mon Jan 2 00:51:38 2023 -0600 Added support for falling back to 16MB behavior if toolchain isn't updated with latest 32MB stack patch commit 46784aa021e7248ec8ae51b6412e0ae873c50f95 Author: darc <da...@pr...> Date: Mon Jan 2 00:38:50 2023 -0600 Kernel patches to enable 32MB memory size on modified Dreamcasts and NAOMI systems ----------------------------------------------------------------------- Summary of changes: AUTHORS | 1 + examples/dreamcast/basic/Makefile | 5 +- .../{pvr/cheap_shadow => basic/memtest32}/Makefile | 8 +- examples/dreamcast/basic/memtest32/main.c | 117 +++++++ examples/dreamcast/basic/memtest32/memtest.c | 221 ++++++++++++ examples/dreamcast/basic/memtest32/memtest.h | 42 +++ kernel/arch/dreamcast/include/arch/arch.h | 41 ++- kernel/arch/dreamcast/kernel/stack.c | 2 +- kernel/arch/dreamcast/kernel/startup.s | 34 +- kernel/mm/malloc_debug.c | 4 +- .../dc-chain/patches/arm-Darwin/gcc-9.3.0-kos.diff | 134 +++++--- utils/dc-chain/patches/gcc-4.7.4-kos.diff | 381 ++++++++++++--------- utils/dc-chain/patches/gcc-9.3.0-kos.diff | 99 ++++-- 13 files changed, 824 insertions(+), 265 deletions(-) copy examples/dreamcast/{pvr/cheap_shadow => basic/memtest32}/Makefile (76%) create mode 100644 examples/dreamcast/basic/memtest32/main.c create mode 100644 examples/dreamcast/basic/memtest32/memtest.c create mode 100644 examples/dreamcast/basic/memtest32/memtest.h diff --git a/AUTHORS b/AUTHORS index 47262fc..22418b6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -42,6 +42,7 @@ Josh Pearson: 2013, 2014, 2015, 2016 Joe Fenton: 2016 Stefan Galowicz: 2016, 2017 Luke Benstead: 2020, 2021 +Eric Fradella: 2023 Files with Specific licenses: ----------------------------- diff --git a/examples/dreamcast/basic/Makefile b/examples/dreamcast/basic/Makefile index bc39b0b..ff28d33 100644 --- a/examples/dreamcast/basic/Makefile +++ b/examples/dreamcast/basic/Makefile @@ -12,6 +12,7 @@ all: $(KOS_MAKE) -C stacktrace $(KOS_MAKE) -C mmu $(KOS_MAKE) -C stackprotector + $(KOS_MAKE) -C memtest32 clean: $(KOS_MAKE) -C exec clean @@ -21,6 +22,7 @@ clean: $(KOS_MAKE) -C stacktrace clean $(KOS_MAKE) -C mmu clean $(KOS_MAKE) -C stackprotector clean + $(KOS_MAKE) -C memtest32 clean dist: $(KOS_MAKE) -C exec dist @@ -30,5 +32,4 @@ dist: $(KOS_MAKE) -C stacktrace dist $(KOS_MAKE) -C mmu dist $(KOS_MAKE) -C stackprotector dist - - + $(KOS_MAKE) -C memtest32 dist diff --git a/examples/dreamcast/pvr/cheap_shadow/Makefile b/examples/dreamcast/basic/memtest32/Makefile similarity index 76% copy from examples/dreamcast/pvr/cheap_shadow/Makefile copy to examples/dreamcast/basic/memtest32/Makefile index ddce956..d488acc 100644 --- a/examples/dreamcast/pvr/cheap_shadow/Makefile +++ b/examples/dreamcast/basic/memtest32/Makefile @@ -1,5 +1,6 @@ -TARGET = shadow.elf -OBJS = shadow.o +TARGET = memtest32.elf + +OBJS = memtest.o main.o all: rm-elf $(TARGET) @@ -15,9 +16,8 @@ $(TARGET): $(OBJS) kos-cc -o $(TARGET) $(OBJS) run: $(TARGET) - $(KOS_LOADER) $(TARGET) -n + $(KOS_LOADER) $(TARGET) dist: rm -f $(OBJS) $(KOS_STRIP) $(TARGET) - diff --git a/examples/dreamcast/basic/memtest32/main.c b/examples/dreamcast/basic/memtest32/main.c new file mode 100644 index 0000000..bf32d5f --- /dev/null +++ b/examples/dreamcast/basic/memtest32/main.c @@ -0,0 +1,117 @@ +/* KallistiOS ##version## + + main.c + Copyright (C) 2020 Thomas Sowell + Copyright (C) 2022 Eric Fradella + + This application illustrates the use of functions related to detecting the + size of system memory and altering a program's behavior to suit the running + system's configuration. + + Implemented is a memory test utility for Dreamcast consoles (both stock 16MB + systems and modified 32MB systems) or NAOMI systems, based on public domain + code by Michael Barr in memtest.c found here: + https://barrgroup.com/embedded-systems/how-to/memory-test-suite-c + + Example output on a functional 32MB-modified Dreamcast: + + Beginning memtest routine... + Base address: 0x8c100000 + Number of bytes to test: 32440320 + memTestDataBus: PASS + memTestAddressBus: PASS + memTestDevice: PASS + Test passed! +*/ + +#include <stdio.h> +#include <stdint.h> + +#include "memtest.h" + +/* Leave space at the beginning and end of memory for this program and for the + * stack. Dreamcast applications are loaded at 0x8c000000 so we leave 0x100000 + * bytes past that for the program itself and leave 65536 bytes at the top of + * memory for the stack. */ +#define SAFE_AREA 0x100000 +#define STACK_SIZE 65536 +#define BASE_ADDRESS (volatile datum *) (0x8c000000 + SAFE_AREA) + +/* Define the number of bytes to be tested. KallistiOS provides the + * macros HW_MEM_16 and HW_MEM_32 which describe the number of bytes + * available in standard supported console configurations (16777216 + * and 33554432, respectively). */ +#define NUM_BYTES_32 (HW_MEM_32 - SAFE_AREA - STACK_SIZE) +#define NUM_BYTES_16 (HW_MEM_16 - SAFE_AREA - STACK_SIZE) + +int main(int argc, char **argv) { + uint32_t error, data, *address; + unsigned long num_bytes; + error = 0; + + /* The HW_MEMSIZE can be called to retrieve the system's memory size. + * _arch_mem_top defines the top address of memory. + * 0x8d000000 if 16MB console, 0x8e000000 if 32MB */ + printf("\nThis console has %ld bytes of system memory,\n with top of " + "memory located at 0x%0lx.\n\n", HW_MEMSIZE, _arch_mem_top); + + /* The DBL_MEM boolean macro is provided as an easy, concise + * way to determine if extra system RAM is available */ + num_bytes = DBL_MEM ? NUM_BYTES_32 : NUM_BYTES_16; + + printf("Beginning memtest routine...\n"); + printf(" Base address: %p\n", BASE_ADDRESS); + printf(" Number of bytes to test: %lu\n", num_bytes); + + /* Now we run the test routines provided in memtest.c + * Each routine returns zero if the routine passes, + * else it returns the address of failure. + * First, let's test the data bus. */ + printf(" memTestDataBus: "); + fflush(stdout); + data = memTestDataBus(BASE_ADDRESS); + + if(data != 0) { + printf("FAIL: %08lx\n", data); + error = 1; + } + else { + printf("PASS\n"); + } + + fflush(stdout); + + /* Now we test the address bus. */ + printf(" memTestAddressBus: "); + fflush(stdout); + address = memTestAddressBus(BASE_ADDRESS, num_bytes); + + if(address != NULL) { + printf("FAIL (%p)\n", address); + error = 1; + } + else { + printf("PASS\n"); + } + + fflush(stdout); + + /* And now, we test the memory itself. */ + printf(" memTestDevice: "); + fflush(stdout); + address = memTestDevice(BASE_ADDRESS, num_bytes); + + if(address != NULL) { + printf("FAIL (%p)\n", address); + error = 1; + } + else { + printf("PASS\n"); + } + + fflush(stdout); + + /* Test completed, return final result */ + printf("Test %s\n", error ? "failed." : "passed!\n"); + return error; +} diff --git a/examples/dreamcast/basic/memtest32/memtest.c b/examples/dreamcast/basic/memtest32/memtest.c new file mode 100644 index 0000000..5321600 --- /dev/null +++ b/examples/dreamcast/basic/memtest32/memtest.c @@ -0,0 +1,221 @@ +/********************************************************************** + * + * Filename: memtest.c + * + * Description: General-purpose memory testing functions. + * + * Notes: This software can be easily ported to systems with + * different data bus widths by redefining 'datum'. + * + * + * Copyright (c) 1998 by Michael Barr. This software is placed into + * the public domain and may be used for any purpose. However, this + * notice must not be changed or removed and no warranty is either + * expressed or implied by its publication or distribution. + **********************************************************************/ + + +#include "memtest.h" + + +/********************************************************************** + * + * Function: memTestDataBus() + * + * Description: Test the data bus wiring in a memory region by + * performing a walking 1's test at a fixed address + * within that region. The address (and hence the + * memory region) is selected by the caller. + * + * Notes: + * + * Returns: 0 if the test succeeds. + * A non-zero result is the first pattern that failed. + * + **********************************************************************/ +datum +memTestDataBus(volatile datum * address) +{ + datum pattern; + + + /* + * Perform a walking 1's test at the given address. + */ + for (pattern = 1; pattern != 0; pattern <<= 1) + { + /* + * Write the test pattern. + */ + *address = pattern; + + /* + * Read it back (immediately is okay for this test). + */ + if (*address != pattern) + { + return (pattern); + } + } + + return (0); + +} /* memTestDataBus() */ + + +/********************************************************************** + * + * Function: memTestAddressBus() + * + * Description: Test the address bus wiring in a memory region by + * performing a walking 1's test on the relevant bits + * of the address and checking for aliasing. This test + * will find single-bit address failures such as stuck + * -high, stuck-low, and shorted pins. The base address + * and size of the region are selected by the caller. + * + * Notes: For best results, the selected base address should + * have enough LSB 0's to guarantee single address bit + * changes. For example, to test a 64-Kbyte region, + * select a base address on a 64-Kbyte boundary. Also, + * select the region size as a power-of-two--if at all + * possible. + * + * Returns: NULL if the test succeeds. + * A non-zero result is the first address at which an + * aliasing problem was uncovered. By examining the + * contents of memory, it may be possible to gather + * additional information about the problem. + * + **********************************************************************/ +datum * +memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes) +{ + unsigned long addressMask = (nBytes/sizeof(datum) - 1); + unsigned long offset; + unsigned long testOffset; + + datum pattern = (datum) 0xAAAAAAAA; + datum antipattern = (datum) 0x55555555; + + + /* + * Write the default pattern at each of the power-of-two offsets. + */ + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + baseAddress[offset] = pattern; + } + + /* + * Check for address bits stuck high. + */ + testOffset = 0; + baseAddress[testOffset] = antipattern; + + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + if (baseAddress[offset] != pattern) + { + return ((datum *) &baseAddress[offset]); + } + } + + baseAddress[testOffset] = pattern; + + /* + * Check for address bits stuck low or shorted. + */ + for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1) + { + baseAddress[testOffset] = antipattern; + + if (baseAddress[0] != pattern) + { + return ((datum *) &baseAddress[testOffset]); + } + + for (offset = 1; (offset & addressMask) != 0; offset <<= 1) + { + if ((baseAddress[offset] != pattern) && (offset != testOffset)) + { + return ((datum *) &baseAddress[testOffset]); + } + } + + baseAddress[testOffset] = pattern; + } + + return (NULL); + +} /* memTestAddressBus() */ + + +/********************************************************************** + * + * Function: memTestDevice() + * + * Description: Test the integrity of a physical memory device by + * performing an increment/decrement test over the + * entire region. In the process every storage bit + * in the device is tested as a zero and a one. The + * base address and the size of the region are + * selected by the caller. + * + * Notes: + * + * Returns: NULL if the test succeeds. + * + * A non-zero result is the first address at which an + * incorrect value was read back. By examining the + * contents of memory, it may be possible to gather + * additional information about the problem. + * + **********************************************************************/ +datum * +memTestDevice(volatile datum * baseAddress, unsigned long nBytes) +{ + unsigned long offset; + unsigned long nWords = nBytes / sizeof(datum); + + datum pattern; + datum antipattern; + + + /* + * Fill memory with a known pattern. + */ + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + { + baseAddress[offset] = pattern; + } + + /* + * Check each location and invert it for the second pass. + */ + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + { + if (baseAddress[offset] != pattern) + { + return ((datum *) &baseAddress[offset]); + } + + antipattern = ~pattern; + baseAddress[offset] = antipattern; + } + + /* + * Check each location for the inverted pattern and zero it. + */ + for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) + { + antipattern = ~pattern; + if (baseAddress[offset] != antipattern) + { + return ((datum *) &baseAddress[offset]); + } + } + + return (NULL); + +} /* memTestDevice() */ diff --git a/examples/dreamcast/basic/memtest32/memtest.h b/examples/dreamcast/basic/memtest32/memtest.h new file mode 100644 index 0000000..381b097 --- /dev/null +++ b/examples/dreamcast/basic/memtest32/memtest.h @@ -0,0 +1,42 @@ +/********************************************************************** + * + * Filename: memtest.h + * + * Description: Memory-testing module API. + * + * Notes: The memory tests can be easily ported to systems with + * different data bus widths by redefining 'datum' type. + * + * + * Copyright (c) 2000 by Michael Barr. This software is placed into + * the public domain and may be used for any purpose. However, this + * notice must not be changed or removed and no warranty is either + * expressed or implied by its publication or distribution. + **********************************************************************/ + +#ifndef _memtest_h +#define _memtest_h + +#include <stdint.h> + +/* + * Define NULL pointer value. + */ +#ifndef NULL +#define NULL (void *) 0 +#endif + +/* + * Set the data bus width. + */ +typedef uint32_t datum; + +/* + * Function prototypes. + */ +datum memTestDataBus(volatile datum * address); +datum * memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes); +datum * memTestDevice(volatile datum * baseAddress, unsigned long nBytes); + + +#endif /* _memtest_h */ diff --git a/kernel/arch/dreamcast/include/arch/arch.h b/kernel/arch/dreamcast/include/arch/arch.h index 2e53d22..62e29df 100644 --- a/kernel/arch/dreamcast/include/arch/arch.h +++ b/kernel/arch/dreamcast/include/arch/arch.h @@ -23,18 +23,24 @@ __BEGIN_DECLS #include <dc/video.h> +/** \brief Top of memory available, depending on memory size. */ +#ifdef __KOS_GCC_32MB__ +extern uint32 _arch_mem_top; +#else +#pragma message "Outdated toolchain: not patched for 32MB support, limiting KOS"\ + " to 16MB-only behavior to retain maximum compatibility. Please"\ + " update toolchain." +#define _arch_mem_top ((uint32) 0x8d000000) +#endif + #define PAGESIZE 4096 /**< \brief Page size (for MMU) */ #define PAGESIZE_BITS 12 /**< \brief Bits for page size */ #define PAGEMASK (PAGESIZE - 1) /**< \brief Mask for page offset */ -#ifndef _arch_sub_naomi /** \brief Page count "variable". The number of pages is static, so we can optimize this quite a bit. */ -#define page_count ((16*1024*1024 - 0x10000) / PAGESIZE) -#else -#define page_count ((32*1024*1024 - 0x10000) / PAGESIZE) ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |