#include "amigalib.h"
#include "debug.h"
+#define MAGIC 0xa55a
+#define STACK_SIZE 4096
+
+enum {
+ MEM_FAST,
+ MEM_SLOW,
+ MEM_CHIP,
+ MEM_USED = 0x8000
+};
+
+struct memrange {
+ uint16_t magic;
+ uint16_t attr;
+ uint32_t size;
+ struct memrange *next;
+ unsigned char start[];
+};
+
+#define NUM_POOLS 3
+static struct memrange *pool[NUM_POOLS];
+static uint32_t stack_base, stack_top;
+
+extern int _mem_start;
+
+void move_init_stack(uint32_t newtop); /* in startup.s */
+
int init_mem(void)
{
+ int i;
+ struct memrange *mr;
struct alib_memnode *mem;
+ uint32_t mem_start = (uint32_t)&_mem_start;
- printf("chip memory top: %lx\n", (unsigned long)execbase->chipmem_top);
- printf("ext memory top: %lx\n", (unsigned long)execbase->extmem_top);
+ printf("mem_start: %lu\n", mem_start);
printf("Memory ranges:\n");
mem = execbase->memlist.head;
while(mem->n_next) {
+ unsigned long start, end, size;
char *stype;
+ int type;
+
+ /* assume we're dealing with at least 64k blocks */
+ start = (unsigned long)mem->start & 0xff0000;
+ end = ((unsigned long)mem->end + 0xffff) & 0xff0000;
+ size = end - start;
+
if(mem->attrib & ALIB_MEMF_CHIP) {
stype = "chip";
+ type = MEM_CHIP;
} else if(mem->attrib & ALIB_MEMF_FAST) {
- stype = "fast";
+ if(start >= 0xc00000 && end <= 0xd80000) {
+ stype = "slow";
+ type = MEM_SLOW;
+ } else {
+ stype = "fast";
+ type = MEM_FAST;
+ }
} else {
- stype = "unknown";
+ printf("ignoring memory range %06lx - %06lx of unknown type: %u\n",
+ start, end, mem->attrib);
+ mem = mem->n_next;
+ continue;
}
- printf(" %06lx - %06lx: %s\n", (unsigned long)mem->start,
- (unsigned long)mem->end, stype);
+
+ printf(" %06lx - %06lx: %s (%ldk)\n", start, end, stype, size >> 10);
mem = mem->n_next;
+
+ if(mem_start >= start && mem_start < end) {
+ size -= mem_start - start;
+ start = mem_start;
+ }
+
+ mr = (struct memrange*)start;
+ mr->magic = MAGIC;
+ mr->attr = type;
+ mr->size = size - sizeof *mr;
+ mr->next = pool[type];
+ pool[type] = mr;
}
+ /* allocate stack space at the top of a memory range, order of preference:
+ * fast, slow, chip
+ */
+ for(i=0; i<NUM_POOLS; i++) {
+ mr = pool[i];
+ if(mr && mr->size >= STACK_SIZE) {
+ stack_top = (uint32_t)mr->start + mr->size;
+ stack_base = stack_top - STACK_SIZE;
+ mr->size -= STACK_SIZE;
+ break;
+ }
+ }
+
+ if(!stack_base) {
+ panic("Failed to allocate stack, no suitable memory ranges found!\n");
+ }
+
+ printf("Allocated %dk stack space: %06lx - %06lx\n", STACK_SIZE >> 10, stack_base, stack_top);
+ move_init_stack(stack_top);
+
return 0;
}
| vi:filetype=gas68k:
+ .include "hwregs.inc"
+
+ .global move_init_stack
.global halt_cpu
+ .global panic
.extern main
.section .startup,"a"
move.l #super, 0x80
trap #0
super:
- ori.w #0x0300, %sr | disable interrupts
+ or.w #0x0700, %sr | disable interrupts
| zero the .bss section
move.l #_bss_start, %a0
cmp.l %a0, %a1
bne.s 0b
1:
- | setup the stack at the top of (traditional) chipmem for now
- move.l #0x80000, %sp
- andi.w #0xf8ff, %sr | enable interrupts
+ | setup a temporary stack
+ move.l #0x40000, %sp
+ and.w #0xf8ff, %sr | enable interrupts
| initialize early exception handlers
jsr exc_init
jsr main
0: bra.b 0b
+move_init_stack:
+ move.l #0x40000, %a1 | a1 <- old stack
+ move.l 4(%sp), %a0 | a0 <- new stack
+0: move.l -(%a1), %d0
+ move.l %d0, -(%a0)
+ cmp.l %sp, %a1
+ bhi.s 0b
+ move.l %a0, %sp
+ rts
+
halt_cpu:
stop #0x2700
+
+panic:
+ or.w #0x0700, %sr
+ move.l #0xdff000, %a0
+ move.w #0x7fff, DMACON(%a0) | clear all DMACON bits
+ move.w #0xf00, COLOR0(%a0)
+
+ pea str_panic
+ jsr printf
+ add.l #8, %sp | also get rid of the reutrn address
+
+ jsr printf
+ bra halt_cpu
+
+str_panic: .asciz "Kernel panic!\n~~~~~~~~~~~~~\n"