Coppy original mapping to the higher half
This commit is contained in:
17
Rakefile
17
Rakefile
@@ -144,11 +144,13 @@ namespace :cross do
|
|||||||
cwd = source_directory.dirname + 'build-binutils'
|
cwd = source_directory.dirname + 'build-binutils'
|
||||||
cwd.mkpath
|
cwd.mkpath
|
||||||
options.rootfs.mkpath
|
options.rootfs.mkpath
|
||||||
|
options.sysroot.mkpath
|
||||||
|
|
||||||
env = ENV.slice 'CC', 'CXX'
|
env = ENV.slice 'CC', 'CXX'
|
||||||
configure_options = [
|
configure_options = [
|
||||||
"--prefix=#{options.rootfs.realpath}",
|
"--prefix=#{options.rootfs.realpath}",
|
||||||
"--target=#{options.target}",
|
"--target=#{options.target}",
|
||||||
|
"--with-sysroot=#{options.sysroot.realpath}",
|
||||||
'--disable-nls',
|
'--disable-nls',
|
||||||
'--enable-gprofng=no',
|
'--enable-gprofng=no',
|
||||||
'--disable-werror',
|
'--disable-werror',
|
||||||
@@ -167,7 +169,6 @@ namespace :cross do
|
|||||||
cwd = source_directory.dirname + 'build-gcc'
|
cwd = source_directory.dirname + 'build-gcc'
|
||||||
cwd.mkpath
|
cwd.mkpath
|
||||||
options.rootfs.mkpath
|
options.rootfs.mkpath
|
||||||
options.sysroot.mkpath
|
|
||||||
|
|
||||||
sh 'contrib/download_prerequisites', chdir: source_directory.to_path
|
sh 'contrib/download_prerequisites', chdir: source_directory.to_path
|
||||||
configure_options = options.configuration('-with-') + [
|
configure_options = options.configuration('-with-') + [
|
||||||
@@ -354,10 +355,10 @@ rule '.elna.o' => ->(match) {
|
|||||||
} do |t|
|
} do |t|
|
||||||
options = BuildTarget.new relative_from_tmp(t.name).first
|
options = BuildTarget.new relative_from_tmp(t.name).first
|
||||||
compiler = options.rootfs + "bin/#{options.target}-gcc"
|
compiler = options.rootfs + "bin/#{options.target}-gcc"
|
||||||
flags = ['-O2', '-g3', '-fno-stack-protector'] + options.configuration('m')
|
|
||||||
sources = t.prerequisites.select { |prerequisite| File.extname(prerequisite) == '.elna' }
|
sources = t.prerequisites.select { |prerequisite| File.extname(prerequisite) == '.elna' }
|
||||||
|
|
||||||
system compiler.to_s, *flags, '-c', '-o', t.name, *sources, exception: true
|
system compiler.to_s, '-O2', '-g3', '-fno-stack-protector', *options.configuration('m'),
|
||||||
|
'-c', '-o', t.name, *sources, exception: true
|
||||||
end
|
end
|
||||||
|
|
||||||
rule 'kernel.elf' => ->(match) {
|
rule 'kernel.elf' => ->(match) {
|
||||||
@@ -373,17 +374,17 @@ rule 'kernel.elf' => ->(match) {
|
|||||||
objects << "arch/#{instruction_set}/kernel.ld"
|
objects << "arch/#{instruction_set}/kernel.ld"
|
||||||
} do |t|
|
} do |t|
|
||||||
options = BuildTarget.new relative_from_tmp(t.name).first
|
options = BuildTarget.new relative_from_tmp(t.name).first
|
||||||
compiler = options.rootfs + "bin/#{options.target}-gcc"
|
linker = options.rootfs + options.target + 'bin/ld'
|
||||||
flags = options.configuration('m')
|
|
||||||
objects, linker_script = t.prerequisites.partition { |prerequisite| File.extname(prerequisite) == '.o' }
|
objects, linker_script = t.prerequisites.partition { |prerequisite| File.extname(prerequisite) == '.o' }
|
||||||
|
|
||||||
system compiler.to_s, '-nostdlib', '-T', *linker_script, '-o', t.name, *objects, exception: true
|
system linker.to_s, '-nostdlib', '-T', *linker_script, '-o', t.name, *objects, exception: true
|
||||||
end
|
end
|
||||||
|
|
||||||
task default: 'build/riscv32/kernel.elf'
|
task default: 'build/riscv32/kernel.elf'
|
||||||
task :default do |t|
|
task :default do |t|
|
||||||
QEMU = 'qemu-system-riscv32'
|
QEMU = 'qemu-system-riscv32'
|
||||||
|
|
||||||
system QEMU, '-machine', 'virt', '-bios', 'default', '-nographic', '-serial', 'mon:stdio', '--no-reboot',
|
system QEMU, '-machine', 'virt', '-nographic', '-serial', 'mon:stdio', '--no-reboot',
|
||||||
'-kernel', t.prerequisites.last, exception: true
|
'-bios', '../opensbi-1.7-rv-bin/share/opensbi/ilp32/generic/firmware/fw_jump.bin',
|
||||||
|
'-device', "loader,file=#{t.prerequisites.last}", exception: true
|
||||||
end
|
end
|
||||||
|
@@ -1,23 +1,20 @@
|
|||||||
OUTPUT_ARCH("riscv")
|
OUTPUT_ARCH("riscv")
|
||||||
OUTPUT_FORMAT("elf32-littleriscv")
|
OUTPUT_FORMAT("elf32-littleriscv")
|
||||||
ENTRY(_entry)
|
ENTRY(_start)
|
||||||
|
|
||||||
PHDRS {
|
PHDRS {
|
||||||
boot PT_LOAD FLAGS(5);
|
|
||||||
text PT_LOAD FLAGS(5);
|
text PT_LOAD FLAGS(5);
|
||||||
|
data PT_LOAD FLAGS(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
.text.boot 0x80200000 : {
|
_kernel_base = 0x80400000;
|
||||||
|
_kernel_virtual = 0xc0000000;
|
||||||
|
_kernel_offset = _kernel_virtual - _kernel_base;
|
||||||
|
|
||||||
|
.text _kernel_virtual : AT(ADDR(.text) - _kernel_offset) {
|
||||||
KEEP(*(.text.boot));
|
KEEP(*(.text.boot));
|
||||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
ASSERT(. - ADDR(.text) <= 0x1000, "error: stub larger than one page");
|
||||||
ASSERT(. - ADDR(.text.boot) == 0x1000, "error: stub larger than one page");
|
|
||||||
} :boot
|
|
||||||
|
|
||||||
_kernel_offset = 0x3fdff000;
|
|
||||||
|
|
||||||
.text 0xc0000000 : AT(ADDR(.text) - _kernel_offset) {
|
|
||||||
PROVIDE(__executable_start = . - _kernel_offset);
|
|
||||||
*(.text .text.*);
|
*(.text .text.*);
|
||||||
} :text
|
} :text
|
||||||
|
|
||||||
@@ -33,10 +30,10 @@ SECTIONS {
|
|||||||
|
|
||||||
.data : AT(ADDR(.data) - _kernel_offset) ALIGN(16) {
|
.data : AT(ADDR(.data) - _kernel_offset) ALIGN(16) {
|
||||||
*(.data .data.*);
|
*(.data .data.*);
|
||||||
}
|
} :data
|
||||||
|
|
||||||
.bss (NOLOAD) : {
|
.bss (NOLOAD) : {
|
||||||
PROVIDE(__bss_start = . - _kernel_offset);
|
PROVIDE(__bss_start = .);
|
||||||
*(.bss .bss.* .sbss .sbss.*);
|
*(.bss .bss.* .sbss .sbss.*);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,10 +1,253 @@
|
|||||||
.global _entry
|
|
||||||
|
|
||||||
.section .rodata
|
.section .rodata
|
||||||
|
|
||||||
panic_message: .asciz "\nPanic"
|
panic_message: .asciz "\nPanic"
|
||||||
.equ PANIC_MESSAGE_SIZE, . - panic_message
|
.equ PANIC_MESSAGE_SIZE, . - panic_message
|
||||||
|
|
||||||
|
.section .text.boot
|
||||||
|
|
||||||
|
.type _start, @function
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
mv s1, a1 # Save the device tree pointer.
|
||||||
|
auipc s2, 0 # Save the physical start of the text section.
|
||||||
|
|
||||||
|
# Set the stack pointer.
|
||||||
|
lui sp, %hi(end)
|
||||||
|
addi sp, sp, %lo(end)
|
||||||
|
li t0, 64 * 1024
|
||||||
|
add sp, sp, t0
|
||||||
|
|
||||||
|
mv a0, s2
|
||||||
|
mv a1, sp
|
||||||
|
jal imem_initialize
|
||||||
|
jal imem_mirror
|
||||||
|
|
||||||
|
la a0, __bss_start
|
||||||
|
la a1, end
|
||||||
|
call bzero
|
||||||
|
|
||||||
|
lui t0, %hi(trap_routine)
|
||||||
|
addi t0, t0, %lo(trap_routine)
|
||||||
|
csrw stvec, t0
|
||||||
|
|
||||||
|
mv a0, sp
|
||||||
|
mv a1, s1
|
||||||
|
|
||||||
|
lui t0, %hi(kernel_main)
|
||||||
|
jr t0, %lo(kernel_main)
|
||||||
|
|
||||||
|
# Copies the identity mappings to the higher half.
|
||||||
|
.type imem_mirror, @function
|
||||||
|
imem_mirror:
|
||||||
|
csrr t0, satp
|
||||||
|
slli t0, t0, 12
|
||||||
|
|
||||||
|
li t3, 0x1000
|
||||||
|
add t1, t0, t3 # Original page table.
|
||||||
|
add t2, t1, t3 # Copied page table.
|
||||||
|
|
||||||
|
mv t3, t2
|
||||||
|
|
||||||
|
.Limem_mirror_copy:
|
||||||
|
lw t4, (t1)
|
||||||
|
sw t4, (t3)
|
||||||
|
|
||||||
|
addi t3, t3, 4
|
||||||
|
addi t1, t1, 4
|
||||||
|
blt t1, t2, .Limem_mirror_copy
|
||||||
|
|
||||||
|
# Persist the copied page table in the root page table.
|
||||||
|
lui t4, %hi(_start)
|
||||||
|
srli t4, t4, 20 # VPN[1] * PTESIZE.
|
||||||
|
add t4, t0, t4 # a + VPN[1] * PTESIZE.
|
||||||
|
srli t3, t2, 2
|
||||||
|
ori t3, t3, 0b1
|
||||||
|
sw t3, (t4)
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
# Activates paging and creates root page table.
|
||||||
|
# Allocates enough pages for the kernel and its stack.
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# a0 - Physical start of the text section.
|
||||||
|
# a1 - Page aligned address following the kernel (kernel end).
|
||||||
|
.type imem_initialize, @function
|
||||||
|
imem_initialize:
|
||||||
|
# Prologue.
|
||||||
|
addi sp, sp, -32
|
||||||
|
sw ra, 28(sp)
|
||||||
|
sw s0, 24(sp)
|
||||||
|
addi s0, sp, 32
|
||||||
|
|
||||||
|
sw a1, 20(sp)
|
||||||
|
sw s1, 16(sp)
|
||||||
|
sw s2, 12(sp)
|
||||||
|
sw s3, 8(sp)
|
||||||
|
|
||||||
|
li s1, 4096
|
||||||
|
add s1, a1, s1
|
||||||
|
# Set boundaries between segments.
|
||||||
|
lui s2, %hi(etext)
|
||||||
|
lui s3, %hi(_data)
|
||||||
|
|
||||||
|
# Set the root page since it is used by mapping functions,
|
||||||
|
# but don't activate paging before the segments are property mapped.
|
||||||
|
srli t0, a1, 12
|
||||||
|
csrw satp, t0
|
||||||
|
|
||||||
|
# Executable section.
|
||||||
|
# a0 is coming from the parameter.
|
||||||
|
addi a1, s2, %lo(etext)
|
||||||
|
mv a2, s1
|
||||||
|
li a3, 1
|
||||||
|
li a4, 0b1010
|
||||||
|
jal imem_map_range
|
||||||
|
|
||||||
|
# Read only section.
|
||||||
|
addi a0, s2, %lo(etext)
|
||||||
|
addi a1, s3, %lo(_data)
|
||||||
|
mv a2, s1
|
||||||
|
li a3, 1
|
||||||
|
li a4, 0b0010
|
||||||
|
jal imem_map_range
|
||||||
|
|
||||||
|
# Data section.
|
||||||
|
addi a0, s3, %lo(_data)
|
||||||
|
lw a1, 20(sp)
|
||||||
|
li t0, 4096 * 3
|
||||||
|
add a1, a1, t0
|
||||||
|
mv a2, s1
|
||||||
|
li a3, 1
|
||||||
|
li a4, 0b0110
|
||||||
|
jal imem_map_range
|
||||||
|
|
||||||
|
# Enable paging.
|
||||||
|
csrr t0, satp
|
||||||
|
li t1, 0x80000000
|
||||||
|
or t0, t0, t1
|
||||||
|
|
||||||
|
sfence.vma
|
||||||
|
csrw satp, t0
|
||||||
|
sfence.vma
|
||||||
|
|
||||||
|
lw s3, 8(sp)
|
||||||
|
lw s2, 12(sp)
|
||||||
|
lw s1, 16(sp)
|
||||||
|
|
||||||
|
# Epilogue.
|
||||||
|
lw ra, 28(sp)
|
||||||
|
lw s0, 24(sp)
|
||||||
|
addi sp, sp, 32
|
||||||
|
ret
|
||||||
|
|
||||||
|
# Maps multiple pages of physical memory to the identical virtual memory.
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# a0 - Start address.
|
||||||
|
# a1 - End address.
|
||||||
|
# a2 - Start of the free memory that can be used to create leaf page tables.
|
||||||
|
# a3 - Page table level. If a3 is 0 a superpage is allocated, otherwise a normal page.
|
||||||
|
# a4 - Flags.
|
||||||
|
.type imem_map_range, @function
|
||||||
|
imem_map_range:
|
||||||
|
# Prologue.
|
||||||
|
addi sp, sp, -32
|
||||||
|
sw ra, 28(sp)
|
||||||
|
sw s0, 24(sp)
|
||||||
|
addi s0, sp, 32
|
||||||
|
|
||||||
|
sw s1, 20(sp)
|
||||||
|
sw a2, 16(sp)
|
||||||
|
sw a3, 12(sp)
|
||||||
|
sw a4, 8(sp)
|
||||||
|
|
||||||
|
mv s1, a1
|
||||||
|
|
||||||
|
.Limem_map_range_loop:
|
||||||
|
bge a0, s1, .Limem_map_range_end
|
||||||
|
|
||||||
|
mv a1, a0
|
||||||
|
lw a2, 16(sp)
|
||||||
|
lw a3, 12(sp)
|
||||||
|
lw a4, 8(sp)
|
||||||
|
jal imem_map_at
|
||||||
|
|
||||||
|
li t0, 4096
|
||||||
|
add a0, a0, t0
|
||||||
|
|
||||||
|
j .Limem_map_range_loop
|
||||||
|
|
||||||
|
.Limem_map_range_end:
|
||||||
|
lw s1, 20(sp)
|
||||||
|
|
||||||
|
# Epilogue.
|
||||||
|
lw ra, 28(sp)
|
||||||
|
lw s0, 24(sp)
|
||||||
|
addi sp, sp, 32
|
||||||
|
ret
|
||||||
|
|
||||||
|
# Maps a page of physical memory to the identical virtual memory.
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# a0 - Corresponding virtual address.
|
||||||
|
# a1 - Physical page address.
|
||||||
|
# a2 - Free memory page that can be used to create a leaf page table.
|
||||||
|
# a3 - Page table level. If a3 is 0 a superpage is allocated, otherwise a normal page.
|
||||||
|
# a4 - Flags.
|
||||||
|
#
|
||||||
|
# Returns virtual page address in a0.
|
||||||
|
.type imem_map_at, @function
|
||||||
|
imem_map_at:
|
||||||
|
csrr t0, satp
|
||||||
|
slli t0, t0, 12 # Root table address.
|
||||||
|
|
||||||
|
li t4, 0xfffffc00
|
||||||
|
li t5, 0xffc # 10 bit * PTESIZE mask.
|
||||||
|
li t1, 20
|
||||||
|
|
||||||
|
.Limem_map_at_loop:
|
||||||
|
# Multiply VPN[i] by 4 and add to the start address of the page table.
|
||||||
|
# This gives the physical address of the page table entry.
|
||||||
|
srl t2, a0, t1
|
||||||
|
and t2, t2, t5 # VPN[i] * PTESIZE.
|
||||||
|
add t2, t0, t2 # a + VPN[i] * PTESIZE.
|
||||||
|
|
||||||
|
beqz a3, .Limem_map_at_leaf
|
||||||
|
|
||||||
|
lw t3, (t2)
|
||||||
|
andi t6, t3, 0b1
|
||||||
|
|
||||||
|
beqz t6, .Limem_map_at_create
|
||||||
|
|
||||||
|
and t0, t3, t4
|
||||||
|
slli t0, t0, 2
|
||||||
|
|
||||||
|
j .Limem_map_at_next
|
||||||
|
|
||||||
|
.Limem_map_at_create:
|
||||||
|
# Take a chunk of free memory and use it as the next page table.
|
||||||
|
# The beginning addres off the chunk is the base address (a) for the next level.
|
||||||
|
mv t0, a2
|
||||||
|
srli t3, t0, 2
|
||||||
|
ori t3, t3, 0b1
|
||||||
|
sw t3, (t2)
|
||||||
|
|
||||||
|
.Limem_map_at_next:
|
||||||
|
# Calculate the next page table address for the next level.
|
||||||
|
addi t1, t1, -10
|
||||||
|
addi a3, a3, -1
|
||||||
|
|
||||||
|
j .Limem_map_at_loop
|
||||||
|
|
||||||
|
.Limem_map_at_leaf:
|
||||||
|
srli t3, a1, 2 # Physical page number mapped to 12 bits of the page table entry.
|
||||||
|
ori a4, a4, 0b1
|
||||||
|
or t3, t3, a4 # Execute, write, read and valid.
|
||||||
|
sw t3, (t2)
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
.section .text
|
.section .text
|
||||||
|
|
||||||
.type kernel_main, @function
|
.type kernel_main, @function
|
||||||
@@ -18,9 +261,6 @@ kernel_main:
|
|||||||
sw a0, 20(sp)
|
sw a0, 20(sp)
|
||||||
sw a1, 16(sp)
|
sw a1, 16(sp)
|
||||||
|
|
||||||
la t0, kernel_entry
|
|
||||||
csrw stvec, t0
|
|
||||||
|
|
||||||
# Map flat device tree to the virtual memory.
|
# Map flat device tree to the virtual memory.
|
||||||
lw a0, 16(sp)
|
lw a0, 16(sp)
|
||||||
li t0, 0xffc00000
|
li t0, 0xffc00000
|
||||||
@@ -45,8 +285,8 @@ kernel_main:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
.balign 4
|
.balign 4
|
||||||
.type kernel_entry, @function
|
.type trap_routine, @function
|
||||||
kernel_entry:
|
trap_routine:
|
||||||
csrw sscratch, sp
|
csrw sscratch, sp
|
||||||
addi sp, sp, -4 * 31
|
addi sp, sp, -4 * 31
|
||||||
|
|
||||||
@@ -184,217 +424,3 @@ panic:
|
|||||||
lw s0, 24(sp)
|
lw s0, 24(sp)
|
||||||
addi sp, sp, 32
|
addi sp, sp, 32
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.section .text.boot
|
|
||||||
_entry:
|
|
||||||
# Set the stack pointer.
|
|
||||||
la t0, end
|
|
||||||
li t1, 64 * 1024
|
|
||||||
add sp, t0, t1
|
|
||||||
|
|
||||||
mv s1, a1
|
|
||||||
|
|
||||||
mv a0, sp
|
|
||||||
call imem_initialize
|
|
||||||
|
|
||||||
li s2, 0xc0000000
|
|
||||||
li s3, 0x80201000
|
|
||||||
li s4, 0x1000
|
|
||||||
|
|
||||||
.rept 12
|
|
||||||
mv a0, s2
|
|
||||||
mv a1, s3
|
|
||||||
li t0, 8192
|
|
||||||
add a2, sp, t0
|
|
||||||
li a3, 1
|
|
||||||
li a4, 0b1110
|
|
||||||
call imem_map_at
|
|
||||||
|
|
||||||
add s2, s2, s4
|
|
||||||
add s3, s3, s4
|
|
||||||
.endr
|
|
||||||
|
|
||||||
la a0, __bss_start
|
|
||||||
la a1, end
|
|
||||||
call bzero
|
|
||||||
|
|
||||||
mv a0, sp
|
|
||||||
mv a1, s1
|
|
||||||
tail kernel_main
|
|
||||||
|
|
||||||
# Activates paging and creates root page table.
|
|
||||||
# Allocates enough pages for the kernel and its stack.
|
|
||||||
#
|
|
||||||
# Parameters:
|
|
||||||
# a0 - Page aligned address following the kernel (kernel end).
|
|
||||||
.type imem_initialize, @function
|
|
||||||
imem_initialize:
|
|
||||||
# Prologue.
|
|
||||||
addi sp, sp, -32
|
|
||||||
sw ra, 28(sp)
|
|
||||||
sw s0, 24(sp)
|
|
||||||
addi s0, sp, 32
|
|
||||||
|
|
||||||
sw a0, 20(sp)
|
|
||||||
|
|
||||||
srli t0, a0, 12
|
|
||||||
csrw satp, t0
|
|
||||||
|
|
||||||
la a0, .text.boot
|
|
||||||
mv a1, a0
|
|
||||||
lw a2, 20(sp)
|
|
||||||
li t0, 4096
|
|
||||||
add a2, a2, t0
|
|
||||||
li a3, 1
|
|
||||||
li a4, 0b1010
|
|
||||||
call imem_map_at
|
|
||||||
|
|
||||||
la a0, __executable_start
|
|
||||||
la a1, etext
|
|
||||||
lw a2, 20(sp)
|
|
||||||
li t0, 4096
|
|
||||||
add a2, a2, t0
|
|
||||||
li a3, 1
|
|
||||||
li a4, 0b1010
|
|
||||||
call imem_map_range
|
|
||||||
|
|
||||||
la a0, etext
|
|
||||||
la a1, _data
|
|
||||||
lw a2, 20(sp)
|
|
||||||
li t0, 4096
|
|
||||||
add a2, a2, t0
|
|
||||||
li a3, 1
|
|
||||||
li a4, 0b0010
|
|
||||||
call imem_map_range
|
|
||||||
|
|
||||||
la a0, _data
|
|
||||||
lw a1, 20(sp)
|
|
||||||
li t0, 4096
|
|
||||||
add a1, a1, t0
|
|
||||||
add a1, a1, t0
|
|
||||||
add a1, a1, t0
|
|
||||||
add a2, a1, t0
|
|
||||||
li a3, 1
|
|
||||||
li a4, 0b0110
|
|
||||||
call imem_map_range
|
|
||||||
|
|
||||||
csrr t0, satp
|
|
||||||
li t1, 0x80000000
|
|
||||||
or t0, t0, t1
|
|
||||||
|
|
||||||
sfence.vma
|
|
||||||
csrw satp, t0
|
|
||||||
sfence.vma
|
|
||||||
|
|
||||||
# Epilogue.
|
|
||||||
lw ra, 28(sp)
|
|
||||||
lw s0, 24(sp)
|
|
||||||
addi sp, sp, 32
|
|
||||||
ret
|
|
||||||
|
|
||||||
# Maps multiple pages of physical memory to the identical virtual memory.
|
|
||||||
#
|
|
||||||
# Parameters:
|
|
||||||
# a0 - Start address.
|
|
||||||
# a1 - End address.
|
|
||||||
# a2 - Start of the free memory that can be used to create leaf page tables.
|
|
||||||
# a3 - Page table level. If a3 is 0 a superpage is allocated, otherwise a normal page.
|
|
||||||
# a4 - Flags.
|
|
||||||
.type imem_map_range, @function
|
|
||||||
imem_map_range:
|
|
||||||
# Prologue.
|
|
||||||
addi sp, sp, -32
|
|
||||||
sw ra, 28(sp)
|
|
||||||
sw s0, 24(sp)
|
|
||||||
addi s0, sp, 32
|
|
||||||
|
|
||||||
sw s1, 20(sp)
|
|
||||||
sw a2, 16(sp)
|
|
||||||
sw a3, 12(sp)
|
|
||||||
sw a4, 8(sp)
|
|
||||||
|
|
||||||
mv s1, a1
|
|
||||||
|
|
||||||
.Limem_map_range_loop:
|
|
||||||
bge a0, s1, .Limem_map_range_end
|
|
||||||
|
|
||||||
mv a1, a0
|
|
||||||
lw a2, 16(sp)
|
|
||||||
lw a3, 12(sp)
|
|
||||||
lw a4, 8(sp)
|
|
||||||
call imem_map_at
|
|
||||||
|
|
||||||
li t0, 4096
|
|
||||||
add a0, a0, t0
|
|
||||||
|
|
||||||
j .Limem_map_range_loop
|
|
||||||
|
|
||||||
.Limem_map_range_end:
|
|
||||||
lw s1, 20(sp)
|
|
||||||
|
|
||||||
# Epilogue.
|
|
||||||
lw ra, 28(sp)
|
|
||||||
lw s0, 24(sp)
|
|
||||||
addi sp, sp, 32
|
|
||||||
ret
|
|
||||||
|
|
||||||
# Maps a page of physical memory to the identical virtual memory.
|
|
||||||
#
|
|
||||||
# Parameters:
|
|
||||||
# a0 - Physical page address.
|
|
||||||
# a1 - Corresponding virtual address.
|
|
||||||
# a2 - Free memory page that can be used to create a leaf page table.
|
|
||||||
# a3 - Page table level. If a3 is 0 a superpage is allocated, otherwise a normal page.
|
|
||||||
# a4 - Flags.
|
|
||||||
#
|
|
||||||
# Returns virtual page address in a0.
|
|
||||||
.type imem_map_at, @function
|
|
||||||
imem_map_at:
|
|
||||||
csrr t0, satp
|
|
||||||
slli t0, t0, 12 # Root table address.
|
|
||||||
|
|
||||||
li t4, 0xfffffc00
|
|
||||||
li t5, 0xffc # 10 bit * PTESIZE mask.
|
|
||||||
li t1, 20
|
|
||||||
|
|
||||||
.Limem_map_at_loop:
|
|
||||||
# Multiply VPN[i] by 4 and add to the start address of the page table.
|
|
||||||
# This gives the physical address of the page table entry.
|
|
||||||
srl t2, a0, t1
|
|
||||||
and t2, t2, t5 # VPN[i] * PTESIZE.
|
|
||||||
add t2, t0, t2 # a + VPN[i] * PTESIZE.
|
|
||||||
|
|
||||||
beqz a3, .Limem_map_at_leaf
|
|
||||||
|
|
||||||
lw t3, (t2)
|
|
||||||
andi t6, t3, 0b1
|
|
||||||
|
|
||||||
beqz t6, .Limem_map_at_create
|
|
||||||
|
|
||||||
and t0, t3, t4
|
|
||||||
slli t0, t0, 2
|
|
||||||
|
|
||||||
j .Limem_map_at_next
|
|
||||||
|
|
||||||
.Limem_map_at_create:
|
|
||||||
# Take a chunk of free memory and use it as the next page table.
|
|
||||||
# The beginning addres off the chunk is the base address (a) for the next level.
|
|
||||||
mv t0, a2
|
|
||||||
srli t3, t0, 2
|
|
||||||
ori t3, t3, 0b1
|
|
||||||
sw t3, (t2)
|
|
||||||
|
|
||||||
.Limem_map_at_next:
|
|
||||||
# Calculate the next page table address for the next level.
|
|
||||||
addi t1, t1, -10
|
|
||||||
addi a3, a3, -1
|
|
||||||
|
|
||||||
j .Limem_map_at_loop
|
|
||||||
|
|
||||||
.Limem_map_at_leaf:
|
|
||||||
srli t3, a1, 2 # Physical page number mapped to 12 bits of the page table entry.
|
|
||||||
ori a4, a4, 0b1
|
|
||||||
or t3, t3, a4 # Execute, write, read and valid.
|
|
||||||
sw t3, (t2)
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
Reference in New Issue
Block a user