2021-06-06 19:38:45 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2021 Travis Geiselbrecht
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a MIT-style
|
|
|
|
|
* license that can be found in the LICENSE file or at
|
|
|
|
|
* https://opensource.org/licenses/MIT
|
|
|
|
|
*/
|
|
|
|
|
#include <lk/asm.h>
|
|
|
|
|
|
|
|
|
|
.section .text.boot
|
|
|
|
|
FUNCTION(_start)
|
2024-02-11 00:38:52 -08:00
|
|
|
// load the first 4 args that were pushed on whatever stack we have
|
|
|
|
|
// NOTE: assumes stack is pointing at at least readable memory
|
2025-09-07 18:20:52 -07:00
|
|
|
movl %sp@(4),%d4
|
|
|
|
|
movl %sp@(8),%d5
|
|
|
|
|
movl %sp@(12),%d6
|
|
|
|
|
movl %sp@(16),%d7
|
2024-02-11 00:38:52 -08:00
|
|
|
|
2022-04-12 00:25:12 -07:00
|
|
|
#if ARCH_DO_RELOCATION
|
|
|
|
|
lea %pc@(_start),%a0 // load the current address using PC relative addressing mode
|
|
|
|
|
movl #_start,%a1 // load the same symbol absolutely
|
|
|
|
|
cmpal %a0,%a1
|
|
|
|
|
beqs bss_clear
|
|
|
|
|
|
|
|
|
|
// load the end address for loop termination
|
|
|
|
|
movl #_end,%a2
|
|
|
|
|
|
|
|
|
|
// copy forwards
|
|
|
|
|
// NOTE: assumes the source and target do not overlap
|
|
|
|
|
0:
|
|
|
|
|
movel %a0@+,%a1@+
|
|
|
|
|
cmpal %a1,%a2
|
|
|
|
|
bne 0b
|
|
|
|
|
|
|
|
|
|
// branch to the new location
|
|
|
|
|
movl #bss_clear,%a0
|
|
|
|
|
jmp %a0@
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-06-06 19:38:45 -07:00
|
|
|
// clear bss
|
2022-04-12 00:25:12 -07:00
|
|
|
bss_clear:
|
2025-09-07 23:50:50 -07:00
|
|
|
#if M68K_CPU >= 68020
|
|
|
|
|
// 020 and above have a full 32bit PC relative addressing mode.
|
|
|
|
|
// Since we may be using a mmu in this case, we may be operating in physical address space,
|
|
|
|
|
// so we need to use PC relative addressing to get the right addresses.
|
2025-09-07 18:20:52 -07:00
|
|
|
lea %pc@(__bss_start),%a0
|
|
|
|
|
lea %pc@(__bss_end),%a1
|
2025-09-07 23:50:50 -07:00
|
|
|
#else
|
|
|
|
|
// We wont be using an MMU on 68000 and 68010, so we can use absolute addresses.
|
|
|
|
|
movl __bss_start,%a0
|
|
|
|
|
movl __bss_end,%a1
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-04-12 00:25:12 -07:00
|
|
|
cmpl %a0,%a1
|
2021-06-06 19:38:45 -07:00
|
|
|
beqs 1f
|
2022-04-12 00:25:12 -07:00
|
|
|
// zero 4 bytes at a time
|
2021-06-06 19:38:45 -07:00
|
|
|
0:
|
2022-04-12 00:25:12 -07:00
|
|
|
clrl %a0@+
|
|
|
|
|
cmpal %a1,%a0
|
|
|
|
|
bne 0b
|
2021-06-06 19:38:45 -07:00
|
|
|
1:
|
|
|
|
|
|
2025-09-07 18:20:52 -07:00
|
|
|
#if M68K_MMU == 68040
|
|
|
|
|
init_mmu_68040:
|
|
|
|
|
// Set up DTTR0 and ITTR0 to map 0x00000000 - 0x3FFFFFFF (1GB) to 0x00000000
|
|
|
|
|
// Logical address base: 0x00000000, mask 0x3f000000, enable, supervisor, cacheble, copyback
|
|
|
|
|
movl #0x003fa020,%d0
|
|
|
|
|
movec %d0,%dtt0
|
|
|
|
|
movec %d0,%itt0
|
|
|
|
|
|
|
|
|
|
// Set up an mapping of [0, MEMSIZE) to [KERNEL_ASPACE_BASE, KERNEL_ASPACE_BASE + MEMSIZE)
|
|
|
|
|
|
|
|
|
|
// Set up L0 entries
|
|
|
|
|
lea %pc@(_root_page_table),%a0
|
|
|
|
|
addl #(KERNEL_ASPACE_BASE / L0_ENTRY_RANGE * 4),%a0 // offset into the middle of the L0 table for KERNEL_ASPACE_BASE
|
|
|
|
|
movl #L0_ENTRIES,%d0
|
|
|
|
|
lea %pc@(_l1_tables),%a1 // get pointer to L1 tables
|
|
|
|
|
addl #0x00000003,%a1 // mark it valid
|
|
|
|
|
.Ll0_loop:
|
|
|
|
|
movl %a1,%a0@ // store it in the L0 table
|
|
|
|
|
addl #4,%a0 // advance to next L0 entry
|
|
|
|
|
addl #L1_PGTABLE_ENTRIES * 4,%a1 // advance to next L1 table
|
|
|
|
|
subl #1,%d0
|
|
|
|
|
bne .Ll0_loop
|
|
|
|
|
|
|
|
|
|
// Set up L1 entries
|
|
|
|
|
lea %pc@(_l1_tables),%a0
|
|
|
|
|
movl #L1_ENTRIES,%d0
|
|
|
|
|
lea %pc@(_l2_tables),%a1 // get pointer to L2 table
|
|
|
|
|
addl #0x00000003,%a1 // mark it valid
|
|
|
|
|
|
|
|
|
|
.Ll1_loop:
|
|
|
|
|
movl %a1,%a0@
|
|
|
|
|
addl #4,%a0
|
|
|
|
|
addl #L2_PGTABLE_ENTRIES * 4,%a1 // advance to next L1 table
|
|
|
|
|
subl #1,%d0
|
|
|
|
|
bne .Ll1_loop
|
|
|
|
|
|
|
|
|
|
// Set up L2 entries
|
|
|
|
|
lea %pc@(_l2_tables),%a0
|
|
|
|
|
movl #L2_ENTRIES,%d0
|
|
|
|
|
movl #0x000000083,%d1 // address 0, supervisor, writable, present
|
|
|
|
|
.L2_loop:
|
|
|
|
|
movl %d1,%a0@ // read the current entry
|
|
|
|
|
addl #4,%a0 // advance to next L2 entry
|
|
|
|
|
addl #PAGE_SIZE,%d1 // advance to next page
|
|
|
|
|
subl #1,%d0
|
|
|
|
|
bne .L2_loop
|
|
|
|
|
|
|
|
|
|
// set the supervisor root pointer
|
|
|
|
|
lea %pc@(_root_page_table),%a0
|
|
|
|
|
movec %a0,%srp
|
|
|
|
|
movec %a0,%urp
|
|
|
|
|
|
|
|
|
|
// enable the mmu
|
|
|
|
|
movl #(1<<15),%d0
|
|
|
|
|
movec %d0,%tc
|
|
|
|
|
|
|
|
|
|
// Branch to the high memory area
|
|
|
|
|
movl #.Lhigh_target,%a0
|
|
|
|
|
jmp %a0@
|
|
|
|
|
.Lhigh_target:
|
|
|
|
|
|
|
|
|
|
// Turn off DTTR0 and ITTR0
|
|
|
|
|
clrl %d0
|
|
|
|
|
movec %d0,%dtt0
|
|
|
|
|
movec %d0,%itt0
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-04-12 00:25:12 -07:00
|
|
|
// load the initial stack pointer
|
|
|
|
|
lea _default_stack_top,%sp
|
2022-02-11 00:37:51 -08:00
|
|
|
|
2024-02-11 00:38:52 -08:00
|
|
|
// branch into C land with 4 args off the previous stack
|
2025-09-07 18:20:52 -07:00
|
|
|
movl %d7,%sp@-
|
|
|
|
|
movl %d6,%sp@-
|
|
|
|
|
movl %d5,%sp@-
|
|
|
|
|
movl %d4,%sp@-
|
2021-06-11 21:34:34 -07:00
|
|
|
jsr lk_main
|
2021-06-06 19:38:45 -07:00
|
|
|
|
2022-04-12 00:25:12 -07:00
|
|
|
// if we return from main just loop forever
|
|
|
|
|
bra .
|
2021-06-06 19:38:45 -07:00
|
|
|
END_FUNCTION(_start)
|
|
|
|
|
|
|
|
|
|
.bss
|
2025-09-07 18:20:52 -07:00
|
|
|
.balign 4
|
2021-06-06 19:38:45 -07:00
|
|
|
_default_stack_base:
|
|
|
|
|
.skip 4096
|
|
|
|
|
_default_stack_top:
|
|
|
|
|
|
2025-09-07 18:20:52 -07:00
|
|
|
#if M68K_MMU == 68040
|
|
|
|
|
// Define space for page tables to set up a mapping of MEMSIZE bytes of memory at KERNEL_ASPACE_BASE
|
|
|
|
|
.equ PAGE_SIZE, 4096
|
|
|
|
|
.equ L0_PGTABLE_ENTRIES, 128 // 7 bits
|
|
|
|
|
.equ L0_ENTRY_RANGE, (1<<25) // each L0 entry covers 32MB
|
|
|
|
|
.equ L1_PGTABLE_ENTRIES, 128 // 7 bits
|
|
|
|
|
.equ L1_ENTRY_RANGE, (1<<18) // each L1 entry covers 256KB
|
|
|
|
|
.equ L2_PGTABLE_ENTRIES, 64 // 6 bits
|
|
|
|
|
|
|
|
|
|
// Number of entries at each level to fill in order to cover MEMSIZE,
|
|
|
|
|
// rounded up to the next L0 entry range so all of the L1 and L2 page tables are fully used.
|
|
|
|
|
.equ MEMSIZE_ROUNDED, (MEMSIZE + L0_ENTRY_RANGE - 1) & ~(L0_ENTRY_RANGE - 1)
|
|
|
|
|
.equ L0_ENTRIES, MEMSIZE_ROUNDED / L0_ENTRY_RANGE
|
|
|
|
|
.equ L1_ENTRIES, MEMSIZE_ROUNDED / L1_ENTRY_RANGE
|
|
|
|
|
.equ L2_ENTRIES, MEMSIZE_ROUNDED / PAGE_SIZE
|
|
|
|
|
|
|
|
|
|
.balign 4096
|
|
|
|
|
_root_page_table:
|
|
|
|
|
.skip L0_PGTABLE_ENTRIES * 4 // 128 entries, 4 bytes each
|
|
|
|
|
.balign 4096
|
|
|
|
|
_l1_tables:
|
|
|
|
|
.skip L1_ENTRIES * 4 // 4 bytes each, one per 256KB section of memory
|
|
|
|
|
.balign 4096
|
|
|
|
|
_l2_tables:
|
|
|
|
|
.skip L2_ENTRIES * 4 // 4 bytes each, one per page of memory
|
|
|
|
|
|
|
|
|
|
#endif // M68K_MMU == 68040
|