diff options
author | vetch <vetch97@gmail.com> | 2020-01-13 12:40:38 +0100 |
---|---|---|
committer | vetch <vetch97@gmail.com> | 2020-01-13 12:40:38 +0100 |
commit | 1af7591e37d09ddcd734ea07d0e999cf61c8bc5e (patch) | |
tree | a56c73c9eddeb148baffc3a31bf50edbbeb31074 /src/arm/PL1/kernel/setup.c | |
parent | 300cf770698142b636da867b7e04bf2d6ae9baa4 (diff) | |
download | rpi-MMU-example-1af7591e37d09ddcd734ea07d0e999cf61c8bc5e.tar.gz rpi-MMU-example-1af7591e37d09ddcd734ea07d0e999cf61c8bc5e.zip |
Great Reorganisation, modify structure and makefile
Diffstat (limited to 'src/arm/PL1/kernel/setup.c')
-rw-r--r-- | src/arm/PL1/kernel/setup.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/arm/PL1/kernel/setup.c b/src/arm/PL1/kernel/setup.c new file mode 100644 index 0000000..bf7c9a1 --- /dev/null +++ b/src/arm/PL1/kernel/setup.c @@ -0,0 +1,116 @@ +#include "uart.h" +#include "io.h" +#include "demo_functionality.h" +#include "paging.h" +#include "atags.h" +// for POWER_OF_2() macro... perhaps the macro should be moved +#include "memory.h" +#include "armclock.h" +#include "scheduler.h" + +void setup(uint32_t r0, uint32_t machine_type, + struct atag_header *atags) +{ + uart_init(); + + // When we attach screen session after loading kernel with socat + // we miss kernel's greeting... So we'll make the kernel wait for + // one char we're going to send from within screen + getchar(); + + puts("Hello, kernel World!"); + + prints("ARM machine type: 0x"); printhext(machine_type); puts(""); + + uint32_t memory_size = 0; + + // value 3 introduced by stage1 code means no atags was found + if (r0 == 3) + { + puts ("No ATAGS was found!"); + } + else + { + prints("ATAGS copied to 0x"); + printhex((uint32_t) atags); puts(""); + + puts("__ ATAGS contents __"); + + print_atags(atags); + + puts("__ end of ATAGS contents __"); + + memory_size = find_memory_size(atags); + } + + if (memory_size) + { + char *unit; + uint32_t size_in_unit; + + if (memory_size % POWER_OF_2(10)) + { + unit = "B"; + size_in_unit = memory_size; + } + else if (memory_size % POWER_OF_2(20)) + { + unit = "KB"; + size_in_unit = memory_size / POWER_OF_2(10); + } + else if (memory_size % POWER_OF_2(30)) + { + unit = "MB"; + size_in_unit = memory_size / POWER_OF_2(20); + } + else + { + unit = "GB"; + size_in_unit = memory_size / POWER_OF_2(30); + } + + prints ("memory available: "); + printdect (size_in_unit); + puts (unit); + } + else + { + // Most Pis have more, but qemu might give us little + puts("Couldn't determine available memory - assuming 192MB"); + memory_size = 192 * POWER_OF_2(20); + } + + // assume we need at least one section for PL0 + if (memory_size < PRIVILEGED_MEMORY_END + SECTION_SIZE) + { + puts("Not enough memory to continue"); + while (1); + } + + // prints some info + demo_paging_support(); + + // prints some info + demo_current_mode(); + + setup_pager_structures(memory_size); + + // prints some info and sets upp translation table, turns on MMU + setup_flat_map(); + + puts("Initializing clock"); + // sets some general settings for arm timer + armclk_init(); + + puts("Setting up scheduler's internal structures"); + setup_scheduler_structures(); + + puts("Switching uart to use irqs"); + + // note, that kernel's puts() is still going to use blocking io + uart_irq_enable(); + + // prints some info and sets up a section for PL0 code, loads a blob + // there, then runs scheduler... never, ever, ever returns + demo_setup_PL0(); +} |