diff options
author | vetch <vetch97@gmail.com> | 2020-01-02 17:54:31 +0100 |
---|---|---|
committer | vetch <vetch97@gmail.com> | 2020-01-02 17:54:31 +0100 |
commit | ab7b754bb32022336527c1a2d5d710b95a589d0e (patch) | |
tree | 19f508f06c72efcbdd2cfad46949ed6f1ae45a3c /demo_functionality.c | |
parent | 5e1e6796109c892c4300c3da17c35e7874a40107 (diff) | |
parent | 6bf5a3b8c6e8a5d1cb3fb4880a5d9688ab094c62 (diff) | |
download | rpi-MMU-example-ab7b754bb32022336527c1a2d5d710b95a589d0e.tar.gz rpi-MMU-example-ab7b754bb32022336527c1a2d5d710b95a589d0e.zip |
Merge branch 'bob' of https://repo.or.cz/RPi-MMU-example into alice
# Conflicts:
# .gitignore
# PL0_test.ld
# demo_functionality.c
# interrupt_vector.S
# interrupts.c
# kernel.c
# memory.h
Diffstat (limited to 'demo_functionality.c')
-rw-r--r-- | demo_functionality.c | 179 |
1 files changed, 93 insertions, 86 deletions
diff --git a/demo_functionality.c b/demo_functionality.c index 691cdb1..1ef91a1 100644 --- a/demo_functionality.c +++ b/demo_functionality.c @@ -1,7 +1,11 @@ -#include "uart.h" +#include "io.h" #include "psr.h" #include "memory.h" #include "translation_table_descriptors.h" +#include "ramfs.h" +#include "strings.h" +#include "paging.h" +#include "armclock.h" void demo_paging_support(void) { @@ -13,16 +17,16 @@ void demo_paging_support(void) switch(ID_MMFR0 & 0xf) /* lowest 4 bits indicate VMSA support */ { - case 0 : paging = "no paging\n\r"; break; - case 1 : paging = "implementation defined paging\n\r"; break; - case 2 : paging = "VMSAv6, with cache and TLB type registers\n\r"; break; - case 3 : paging = "VMSAv7, with support for remapping and access flag\n\r"; break; - case 4 : paging = "VMSAv7 with PXN bit supported\n\r"; break; - case 5 : paging = "VMSAv7, PXN and long format descriptors. EPAE is supported.\n\r"; break; - default : paging = "?_? unknown paging ?_?\n\r"; + case 0 : paging = "no paging"; break; + case 1 : paging = "implementation defined paging"; break; + case 2 : paging = "VMSAv6, with cache and TLB type registers"; break; + case 3 : paging = "VMSAv7, with support for remapping and access flag"; break; + case 4 : paging = "VMSAv7 with PXN bit supported"; break; + case 5 : paging = "VMSAv7, PXN and long format descriptors. EPAE is supported."; break; + default : paging = "?_? unknown paging ?_?"; } - uart_puts(paging); + puts(paging); } void demo_current_mode(void) @@ -36,99 +40,102 @@ void demo_current_mode(void) switch(CPSR.fields.PSR_MODE_4_0) { - case MODE_USER : mode_name = "User (PL0)\r\n"; break; - case MODE_FIQ : mode_name = "FIQ (PL1)\r\n"; break; - case MODE_IRQ : mode_name = "IRQ (PL1)\r\n"; break; - case MODE_SUPERVISOR : mode_name = "Supervisor (PL1)\r\n"; break; - case MODE_MONITOR : mode_name = "Monitor (PL1)\r\n"; break; - case MODE_ABORT : mode_name = "Abort (PL1)\r\n"; break; - case MODE_HYPERVISOR : mode_name = "Hyp (PL2)\r\n"; break; - case MODE_UNDEFINED : mode_name = "Undefined (PL1)\r\n"; break; - case MODE_SYSTEM : mode_name = "System (PL1)\r\n"; break; - default : mode_name = "Unknown mode\r\n"; break; + case MODE_USER : mode_name = "User (PL0)"; break; + case MODE_FIQ : mode_name = "FIQ (PL1)"; break; + case MODE_IRQ : mode_name = "IRQ (PL1)"; break; + case MODE_SUPERVISOR : mode_name = "Supervisor (PL1)"; break; + case MODE_MONITOR : mode_name = "Monitor (PL1)"; break; + case MODE_ABORT : mode_name = "Abort (PL1)"; break; + case MODE_HYPERVISOR : mode_name = "Hyp (PL2)"; break; + case MODE_UNDEFINED : mode_name = "Undefined (PL1)"; break; + case MODE_SYSTEM : mode_name = "System (PL1)"; break; + default : mode_name = "Unknown mode"; break; } - uart_puts("current mode: "); - uart_puts(mode_name); + prints("current mode: "); + puts(mode_name); } +#define TRANSLATION_TABLE \ + ((short_section_descriptor_t volatile*) TRANSLATION_TABLE_BASE) + extern char - _binary_PL_0_test_img_start, - _binary_PL_0_test_img_end, - _binary_PL_0_test_img_size; + _binary_ramfs_img_start, + _binary_ramfs_img_end, + _binary_ramfs_img_size; -void demo_go_unprivileged(void) +void demo_setup_PL0(void) { - short_section_descriptor_t *translation_table = - (short_section_descriptor_t*) TRANSLATION_TABLE_BASE; - - volatile short_section_descriptor_t *PL0_section = - &translation_table[PL0_SECTION_NUMBER]; - volatile short_section_descriptor_t *UART_memory_section = - &translation_table[((uint32_t) GPIO_BASE) >> 20]; - - PL0_section->SECTION_BASE_ADDRESS_31_20 = - UNPRIVILEGED_MEMORY_START >> 20; - - // make the selected section and uart section available for PL0 - PL0_section->ACCESS_PERMISSIONS_2 = - AP_2_0_MODEL_RW_ALL >> 2; - PL0_section->ACCESS_PERMISSIONS_1_0 = - AP_2_0_MODEL_RW_ALL & 0b011; - - UART_memory_section->ACCESS_PERMISSIONS_2 = - AP_2_0_MODEL_RW_ALL >> 2; - UART_memory_section->ACCESS_PERMISSIONS_1_0 = - AP_2_0_MODEL_RW_ALL & 0b011; - + // find PL_0_test.img im ramfs + struct ramfile PL_0_test_img; + + if (find_file(&_binary_ramfs_img_start, "PL_0_test.img", + &PL_0_test_img)) + { + puts("PL_0_test.img not found :("); + asm volatile ("wfi"); + } - // invalidate main Translation Lookup Buffer (just in case) - asm("mcr p15, 0, %0, c8, c7, 0\n\r" - "isb" :: "r" (0) : "memory"); + // dummy value 5 for now, as we haven't implemented processes yet + uint16_t physical_section_number = claim_and_map_section + ((void*) 5, PL0_SECTION_NUMBER, AP_2_0_MODEL_RW_ALL); + if (physical_section_number == SECTION_NULL) + { + puts("Couldn't claim memory section for unprivileged code :("); + while(1); + } + + size_t physical_section_start = + (((size_t) physical_section_number) << 20); + // check that translation works... by copying a string using one // mapping and reading it using other :D - char message[] = "mapped sections for PL0 code\n\r"; - - unsigned int i; - for (i = 0; i < sizeof(message); i++) - ((volatile char*) UNPRIVILEGED_MEMORY_START)[i] = message[i]; - - uart_puts((char*) VIRTUAL_PL0_MEMORY_START); - - // now paste a userspace program to that section, jump to it and - // switch to PL0 - for (size_t i = 0; i < (size_t) &_binary_PL_0_test_img_size; i++) - ((volatile char*) VIRTUAL_PL0_MEMORY_START)[i] = - (&_binary_PL_0_test_img_start)[i]; - - // jump to that copied code (switch to PL0 is done by that code) - asm volatile("mov r5, #0\n\r" - "movt r5, #"PL0_SECTION_NUMBER_STR"1111\n\r" - "mov sp, r5\n\r" // setting stack is important :D - "mov r5, #0\n\r" - "movt r5, #"PL0_SECTION_NUMBER_STR"0000\n\r" - "blx r5\n\r"); -} + char str_part1[] = "mapped section for PL0 code (0x"; + char str_part2[] = " -> 0x"; + char str_part3[] = ")"; -extern char - __interrupt_vectors_start, - __interrupt_vectors_end, - __interrupt_vectors_size; + char *string_end = (char*) physical_section_start; -extern void (*volatile system_reentry_point)(void); + memcpy(string_end, str_part1, sizeof(str_part1) - 1); + uint32_to_hex(VIRTUAL_PL0_MEMORY_START, + string_end += sizeof(str_part1) - 1); + memcpy(string_end += 8, str_part2, sizeof(str_part2) - 1); + uint32_to_hex(physical_section_start, + string_end += sizeof(str_part2) - 1); + memcpy(string_end += 8, str_part3, sizeof(str_part3)); -void system_reentry(void) -{ - uart_puts("re-entered system"); - while(1); + puts((char*) VIRTUAL_PL0_MEMORY_START); + + // now paste a userspace program to that section + memcpy((void*) VIRTUAL_PL0_MEMORY_START, + PL_0_test_img.file_contents, PL_0_test_img.file_size); + + puts("copied PL0 code to it's section"); } -void demo_setup_interrupts(void) +void demo_go_unprivileged(void) { - system_reentry_point = system_reentry; + uint32_t PL0_regs[14] = {0}; + PL0_regs[13] = VIRTUAL_PL0_MEMORY_START; // the new pc + + PSR_t new_SPSR = read_CPSR(); + new_SPSR.fields.PSR_MODE_4_0 = MODE_USER; + new_SPSR.fields.PSR_IRQ_MASK_BIT = 0; + write_SPSR(new_SPSR); - for (size_t i = 0; i < (size_t) &__interrupt_vectors_size; i++) - ((volatile char*) 0)[i] = - (&__interrupt_vectors_start)[i]; + puts("All ready, jumping to PL0 code"); + + armclk_irq_settimeout(0x00100000); + + asm volatile("cps %[sysmode]\n\r" + "mov sp, %[stackaddr]\n\r" + "cps %[supmode]\n\r" + "ldm %[contextaddr], {r0 - r12, pc} ^" :: + [sysmode]"I" (MODE_SYSTEM), + [supmode]"I" (MODE_SUPERVISOR), + [stackaddr]"r" ((PL0_SECTION_NUMBER + 1) << 20), + [contextaddr]"r" (PL0_regs) : "memory"); + + __builtin_unreachable(); } |