Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Support Dreamcasts with 32MB system RAM
Only the 9.3.0 patch is updated!
  • Loading branch information
tsowell committed Jun 25, 2020
1 parent 6830519 commit 09aea2b
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 15 deletions.
14 changes: 9 additions & 5 deletions kernel/arch/dreamcast/include/arch/arch.h
Expand Up @@ -136,6 +136,14 @@ void __crtend_pullin();
*/
int mm_init();

/** \brief Determine how much addressable memory is present. On Dreamcast
this checks the MCR to determine which addressing is being used.
Only supports pristine 16MB SDRAM and 32MB SDRAM as described at
https://tsowell.github.io/2020/06/21/dreamcast-32mb-ram-upgrade.html
\return The address that forms the upper bound of system RAM.
*/
uint32 mm_top();

/** \brief Request more core memory from the system.
\param increment The number of bytes requested.
\return A pointer to the memory.
Expand Down Expand Up @@ -354,17 +362,13 @@ const char *kos_get_authors(void);
*/
#define arch_fptr_next(fptr) (*((uint32*)(fptr+4)))

#ifndef _arch_sub_naomi
/** \brief Returns true if the passed address is likely to be valid. Doesn't
have to be exact, just a sort of general idea.
\return Whether the address is valid or not for normal
memory access.
*/
#define arch_valid_address(ptr) ((ptr_t)(ptr) >= 0x8c010000 && (ptr_t)(ptr) < 0x8d000000)
#else
#define arch_valid_address(ptr) ((ptr_t)(ptr) >= 0x8c010000 && (ptr_t)(ptr) < 0x8e000000)
#endif
#define arch_valid_address(ptr) ((ptr_t)(ptr) >= 0x8c010000 && (ptr_t)(ptr) < mm_top())

__END_DECLS

Expand Down
19 changes: 18 additions & 1 deletion kernel/arch/dreamcast/kernel/mm.c
Expand Up @@ -19,6 +19,8 @@
#include <arch/irq.h>
#include <stdio.h>

#define MCR (*((volatile uint32_t *) 0xff800014))

/* The end of the program is always marked by the '_end' symbol. So we'll
longword-align that and add a little for safety. sbrk() calls will
move up from there. */
Expand All @@ -34,6 +36,21 @@ int mm_init() {
return 0;
}

/* Return address at top of system RAM */
uint32 mm_top() {
if (((MCR >> 3) & 0x07) == 3) {
/* AMX 3, assuming 32MB SDRAM */
return 0x8e000000;
}
else {
#ifndef _arch_sub_naomi
return 0x8d000000;
#else
return 0x8e000000;
#endif
}
}

/* Simple sbrk function */
void* mm_sbrk(unsigned long increment) {
int old;
Expand All @@ -46,7 +63,7 @@ void* mm_sbrk(unsigned long increment) {

sbrk_base = (void *)(increment + (unsigned long)sbrk_base);

if(((uint32)sbrk_base) >= (0x8d000000 - 65536)) {
if(((uint32)sbrk_base) >= (mm_top() - 65536)) {
dbglog(DBG_DEAD, "Requested sbrk_base %p, was %p, diff %lu\n",
sbrk_base, base, increment);
arch_panic("out of memory; about to run over kernel stack");
Expand Down
2 changes: 1 addition & 1 deletion kernel/arch/dreamcast/kernel/stack.c
Expand Up @@ -29,7 +29,7 @@ void arch_stk_trace_at(uint32 fp, int n) {
dbgio_printf("-------- Stack Trace (innermost first) ---------\n");

while(fp != 0xffffffff) {
if((fp & 3) || (fp < 0x8c000000) || (fp > 0x8d000000)) {
if((fp & 3) || (fp < 0x8c000000) || (fp > mm_top())) {
dbgio_printf(" (invalid frame pointer)\n");
break;
}
Expand Down
16 changes: 14 additions & 2 deletions kernel/arch/dreamcast/kernel/startup.s
Expand Up @@ -71,7 +71,15 @@ init:
! Save the current stack, and set a new stack (higher up in RAM)
mov.l old_stack_addr,r0
mov.l r15,@r0
mov.l new_stack,r15
! Set stack based on MCR
mov.l new_stack_16m,r15
mov.l mcr,r1
mov.l @r1,r0
and #0x38,r0
cmp/eq #0x18,r0
bf mcr_16m
mov.l new_stack_32m,r15
mcr_16m:

! Save VBR
mov.l old_vbr_addr,r0
Expand Down Expand Up @@ -173,8 +181,12 @@ old_stack_addr:
__arch_old_stack:
old_stack:
.long 0
new_stack:
new_stack_16m:
.long 0x8d000000
new_stack_32m:
.long 0x8e000000
mcr:
.long 0xff800014
p2_mask:
.long 0xa0000000
setup_cache_addr:
Expand Down
4 changes: 2 additions & 2 deletions kernel/mm/malloc_debug.c
Expand Up @@ -108,7 +108,7 @@ void *malloc(size_t amt) {
spinlock_unlock(&mutex);

printf("Thread %d/%08lx allocated %d bytes at %08lx; %08lx left\n",
ctl->thread, ctl->addr, ctl->size, space, 0x8d000000 - (uint32)sbrk(0));
ctl->thread, ctl->addr, ctl->size, space, mm_top() - (uint32)sbrk(0));

assert(!(((uint32)space) & 7));

Expand Down Expand Up @@ -178,7 +178,7 @@ void free(void *block) {
printf("Thread %d/%08x freeing block @ %08x\n",
thd_current->tid, pr, (uint32)block);

if(((uint32)block) & 7 || (uint32)block < 0x8c010000 || (uint32)block >= 0x8d000000) {
if(((uint32)block) & 7 || (uint32)block < 0x8c010000 || (uint32)block >= mm_top()) {
printf(" ATTEMPT TO FREE INVALID ADDRESS!\n");
spinlock_unlock(&mutex);
return;
Expand Down
20 changes: 16 additions & 4 deletions utils/dc-chain/patches/gcc-9.3.0-kos.diff
Expand Up @@ -13,7 +13,7 @@ diff -ruN gcc-9.3.0/gcc/configure gcc-9.3.0-kos/gcc/configure
diff -ruN gcc-9.3.0/libgcc/config/sh/crt1.S gcc-9.3.0-kos/libgcc/config/sh/crt1.S
--- gcc-9.3.0/libgcc/config/sh/crt1.S 2020-03-12 07:07:23.000000000 -0400
+++ gcc-9.3.0-kos/libgcc/config/sh/crt1.S 2020-04-03 16:07:04.540000000 -0400
@@ -1,724 +1,197 @@
@@ -1,724 +1,209 @@
-/* Copyright (C) 2000-2019 Free Software Foundation, Inc.
- This file was pretty much copied from newlib.
+! KallistiOS ##version##
Expand Down Expand Up @@ -232,7 +232,15 @@ diff -ruN gcc-9.3.0/libgcc/config/sh/crt1.S gcc-9.3.0-kos/libgcc/config/sh/crt1.
+ ! Save the current stack, and set a new stack (higher up in RAM)
+ mov.l old_stack_addr,r0
+ mov.l r15,@r0
+ mov.l new_stack,r15
+ ! Set stack based on MCR
+ mov.l new_stack_16m,r15
+ mov.l mcr,r1
+ mov.l @r1,r0
+ and #0x38,r0
+ cmp/eq #0x18,r0
+ bf mcr_16m
+ mov.l new_stack_32m,r15
+mcr_16m:
+
+ ! Save VBR
+ mov.l old_vbr_addr,r0
Expand Down Expand Up @@ -896,8 +904,12 @@ diff -ruN gcc-9.3.0/libgcc/config/sh/crt1.S gcc-9.3.0-kos/libgcc/config/sh/crt1.
+__arch_old_stack:
+old_stack:
+ .long 0
+new_stack:
+ .long 0x8d000000
+new_stack_16m:
+ .long 0x8d000000
+new_stack_32m:
+ .long 0x8e000000
+mcr:
+ .long 0xff800014
+p2_mask:
+ .long 0xa0000000
+setup_cache_addr:
Expand Down

0 comments on commit 09aea2b

Please sign in to comment.