diff --git a/core/hw/board/raspberrypi2/board_mem.c b/core/hw/board/raspberrypi2/board_mem.c index 8bd8882..0170aa5 100755 --- a/core/hw/board/raspberrypi2/board_mem.c +++ b/core/hw/board/raspberrypi2/board_mem.c @@ -72,6 +72,10 @@ memory_layout_entry memory_padr_layout[] = //UART (0x3F201000 to 0x3F20108F) {ADDR_TO_PAGE(UART_BASE), ADDR_TO_PAGE(UART_BASE + 0x1000), MLT_IO_RW_REG, MLF_READABLE | MLF_WRITEABLE}, + + //Quad-Core processor control (0x40000000 to 0x400000FF) + {ADDR_TO_PAGE(0x40000000), ADDR_TO_PAGE(0x40000000 + 0x1000), + MLT_IO_RW_REG, MLF_READABLE | MLF_WRITEABLE}, //////////////////////////////////////////////////////////////////////// diff --git a/core/hw/cpu/arm/arm_common/arm_pt.S b/core/hw/cpu/arm/arm_common/arm_pt.S index f8caa48..a7ac1de 100755 --- a/core/hw/cpu/arm/arm_common/arm_pt.S +++ b/core/hw/cpu/arm/arm_common/arm_pt.S @@ -1,8 +1,10 @@ /* - * ARM pagetable function including the initial setup + * ARM pagetable functions including the initial setup */ .global arm_setup_initial_pt + .global arm_setup_initial_slave_pt + .global arm_reset_initial_pt .code 32 .align 0 @@ -12,7 +14,7 @@ /* * SANITY CHECKS: * - * The code in this page makes some assumptions, check they are true + * The code in this page makes some assumptions, and checks if they are true. */ #if (__hyper_pt_start__ & (1024 * 16-1)) != 0 @@ -23,6 +25,14 @@ #error "__hyper_pt_end__ is not 1K aligned!" #endif +#if (__hyper_pt_start_slave__ & (1024 * 16-1)) != 0 + #error "__hyper_pt_start_slave__ is not 16K aligned!" +#endif + +#if (__hyper_pt_end_slave__ & (1024 * 1-1)) != 0 + #error "__hyper_pt_end_slave__ is not 1K aligned!" +#endif + #if (HAL_PHYS_START & (1024 * 4)) != 0 #error "HAL_PHYS_START is not 4K aligned!" #endif @@ -38,23 +48,25 @@ arm_setup_initial_pt: - /*Start with simplest possible needed to get sth running - in virtual address - */ + /* Start with the simplest possible PT needed to get STH running + * in virtual address space. + */ ldr r4, = (__hyper_pt_start__ + HAL_OFFSET) - jmp arm_setup_initial_pt_at_adr + bl arm_setup_initial_pt_at_adr arm_setup_initial_slave_pt: - /*Start with simplest possible needed to get sth running - in virtual address - */ + /* Start with the simplest possible PT needed to get the second guest + * running in virtual address space (we will switch to the master page table + * later). + */ - ldr r4, = (__hyper_pt_start_core_1__ + HAL_OFFSET) - jmp arm_setup_initial_pt_at_adr + ldr r4, = (__hyper_pt_start_slave__ + HAL_OFFSET) + bl arm_setup_initial_pt_at_adr arm_reset_initial_pt: + ldr r4, = (__hyper_pt_start__ + HAL_OFFSET) mcr p15, 0, r4, c2, c0, 0 @ load page table pointer bx lr @@ -62,7 +74,8 @@ arm_setup_initial_pt_at_adr: mov r0, r4 mov r1, #0 add r2, r0, #0x4000 - /* first, clean the memory used to make all pages invalid */ + + /* First, clean the memory used to make all pages invalid. */ 1: str r1, [r0], #4 str r1, [r0], #4 str r1, [r0], #4 @@ -70,16 +83,16 @@ arm_setup_initial_pt_at_adr: teq r0, r2 bne 1b - /* do a 1->1 temporary mapping for our current position */ + /* Do a 1->1 temporary mapping for our current position. */ ldr r6, =(HAL_PHYS_START >> 20) ldr r7, =(HAL_PHYS_START | 0x40E) @ CB on, Section, XN=f, AP =01 PRIV RW USER NO ACCESS str r7, [r4, r6, lsl #2] @ 1:1 mapping for current position - /* then map us from HAL_VIR_START to HAL_PHY_START in L1 */ + /* Then, map us from HAL_VIR_START to HAL_PHY_START in L1. */ add r0, r4, #(HAL_VIRT_START & 0xff000000) >> 18 str r7, [r0,#(HAL_VIRT_START & 0x00f00000) >> 18]! @ Map phys to HAL_VIRT_START - /*Enable MMU*/ + /* Enable MMU */ mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer mcr p15, 0, r0, c8, c7, 0 @ flush I, D, TLB @@ -92,7 +105,7 @@ arm_setup_initial_pt_at_adr: mcr p15, 0, r0, c1, c0, 0 @ write control reg - /* adjust stack and jump to our virtual address */ + /* Adjust stack and jump to our virtual address. */ ldr r1, =HAL_OFFSET sub sp, sp, r1 sub pc, pc, r1 @@ -100,7 +113,7 @@ arm_setup_initial_pt_at_adr: nop @ for PC jump above nop @ for PC jump above - /*Now running in virt space, we can remove 1:1 mapping now*/ + /* Now running in virt space, we can remove 1:1 mapping now */ mov r0, #0 ldr r3, =(HAL_PHYS_START >> 20) str r0, [r4, r3, lsl #2] diff --git a/core/hw/cpu/arm/armv7a/boot.S b/core/hw/cpu/arm/armv7a/boot.S index 119af18..8d24ea3 100755 --- a/core/hw/cpu/arm/armv7a/boot.S +++ b/core/hw/cpu/arm/armv7a/boot.S @@ -8,9 +8,9 @@ .global impl_reset .global _interrupt_vector_table + .global _hang .extern arm_move_guest_blob - .extern start_ .extern impl_undef .extern impl_swi diff --git a/core/hw/cpu/arm/armv7a/boot_slave.S b/core/hw/cpu/arm/armv7a/boot_slave.S new file mode 100644 index 0000000..7c0b5e5 --- /dev/null +++ b/core/hw/cpu/arm/armv7a/boot_slave.S @@ -0,0 +1,52 @@ +/* + * Boot code for slave guests starting on different ARMv7a cores + * + */ + + .global impl_slave_reset + + .extern arm_move_guest_blob + .extern start_ + .extern impl_undef + .extern impl_swi + .extern impl_pabort + .extern impl_dabort + .extern impl_irq + .extern impl_fiq + + .code 32 + .align 0 + .section .vector,"ax" + +#include "arm_common.h" + + .align 4 + .section .startup, "ax" + +impl_slave_reset: + /* Start in supervisor mode, disable interrupts. */ + msr CPSR_c, #ARM_MODE_SUPERVISOR | ARM_INTERRUPT_MASK + /* Stack pointer starts at the physical address of the hyper stack top. */ + /* ldr sp, =(__hyper_stack_top__ + HAL_OFFSET)*/ /* Switch to another hyper stack, which you create in the linker */ + + /* Clean BSS. + bl arm_clear_bss */ + + /* Setup pages and switch to virtual memory. */ + bl arm_setup_initial_slave_pt + + /* Switch to master page table */ + bl arm_reset_initial_pt + + /* From here on (more precisely, from a point at the end of above function), + * you are in virtual memory! */ + + /* Setup real stacks now, run core init and reclaim the initial stacks. */ + bl arm_setup_initial_stack + + /* Init rest of hypervisor in C. */ + /* start_ can be found in core/hypervisor/init.c */ + bl start_ + + /* Should not be reached! */ + bl _hang diff --git a/core/hw/ld/raspberrypi2.ld b/core/hw/ld/raspberrypi2.ld index b82968a..9d9b379 100644 --- a/core/hw/ld/raspberrypi2.ld +++ b/core/hw/ld/raspberrypi2.ld @@ -63,12 +63,17 @@ SECTIONS . = 0xf0100000 - 1024 * (64 + 32 + 8); __hyper_heap_end__ = .; - /* stack */ + /* Primary stack (core 0) */ __hyper_stack_bottom__ = .; . += 1024 * 8; - __hyper_stack_top__ = .; + __hyper_stack_top__ = .; - /* guest */ + /* Secondary stack (core 1) */ + __hyper_stack_bottom_core_1__ = .; + . += 1024 * 8; + __hyper_stack_top_core_1__ = .; + + /* Guest */ __hyper_guest_start__ = .; . += 1024 * 32; __hyper_guest_end__ = .; @@ -79,6 +84,11 @@ SECTIONS . += 1024 * 64; __hyper_pt_end__ = .; + /* Secondary (slave) PT memory */ + __hyper_pt_start_slave__ = .; + . += 1024 * 64; + __hyper_pt_end_slave__ = .; + __hyper_end__ = .; } diff --git a/core/hw/ld/virt-hyper.ld b/core/hw/ld/virt-hyper.ld index a7e1a5f..46141a2 100644 --- a/core/hw/ld/virt-hyper.ld +++ b/core/hw/ld/virt-hyper.ld @@ -16,8 +16,7 @@ SECTIONS __hyper_start__ = . ; - /*Vector table comes first, reserve 0x1000 for it*/ - + /* Vector table comes first, reserve 0x1000 for it */ .vector : { *.o(.vector) } > VECTOR @@ -26,8 +25,7 @@ SECTIONS *(.kuser) } > KUSER - - . = 0xF0001000; + . = 0xF0001000; __hyper_code_start__ = .; __code_start__ = .; @@ -39,10 +37,8 @@ SECTIONS /* . = ALIGN(__page_size__); */ __hyper_code_end__ = .; - - - /* DATA */ + /* Data */ __hyper_data_start__ = .; .data : { @@ -62,7 +58,6 @@ SECTIONS __data_end__ = .; __hyper_data_end__ = .; - /* BSS */ __hyper_bss_start__ = .; .bss : { @@ -70,29 +65,38 @@ SECTIONS *.to(.bss) } > RAM __hyper_bss_end__ = .; - - /* heap: up to 104K */ + /* Heap: up to 104 KiB */ __hyper_heap_start__ = .; . = 0xf0100000 - 1024 * (64 + 32 + 8); __hyper_heap_end__ = .; - /* stack */ + /* Primary stack (for core 0) */ __hyper_stack_bottom__ = .; . += 1024 * 8; - __hyper_stack_top__ = .; + __hyper_stack_top__ = .; + + /* Secondary stack (for core 1) */ + __hyper_stack_bottom_core_1__ = .; + . += 1024 * 8; + __hyper_stack_top_core_1__ = .; - /* guest */ + /* Guest */ __hyper_guest_start__ = .; . += 1024 * 32; __hyper_guest_end__ = .; - /* PT memory */ + /* PT memory */ . = ALIGN(__page_size__); __hyper_pt_start__ = .; . += 1024 * 64; __hyper_pt_end__ = .; + /* Secondary (slave) PT memory (only needed to run guests on different cores) */ + __hyper_pt_start_slave__ = .; + . += 1024 * 64; + __hyper_pt_end_slave__ = .; + __hyper_end__ = .; } diff --git a/core/hypervisor/init_slave.c b/core/hypervisor/init_slave.c new file mode 100644 index 0000000..6c6e926 --- /dev/null +++ b/core/hypervisor/init_slave.c @@ -0,0 +1,38 @@ +#include +#include "hyper.h" +#include "guest_blob.h" +#include "mmu.h" +#include "hw_core_mem.h" +#include "dmmu.h" +//TODO: Note: Added these to avoid warnings. +extern void dmmu_init(); +extern uint32_t dmmu_map_L1_section(addr_t va, addr_t sec_base_add, uint32_t attrs); +extern void debug_inf(void); //TODO. Remove after debugging + +//Add what you need here in terms of external functions and imports to be able +//to do what you want. + +void slave_start_(){ + //TODO: Which of these needs to be done? + //cpu_init(); + + /* Set up pagetable rules. */ + //memory_init(); + + /* Initialize hardware. */ + //soc_init(); + //board_init(); + + /* Set up exception handlers and starting timer. */ + //setup_handlers(); + + /* DMMU initialization. */ + //dmmu_init(); + + /* Initialize hypervisor guest modes and data structures + * according to config file in guest*/ + //guests_init(); + + //Move along, main core... + //start_guest(); +} diff --git a/rpi2-port/Guide/Guide.tex b/rpi2-port/Guide/Guide.tex index 0276717..4b3d59c 100644 --- a/rpi2-port/Guide/Guide.tex +++ b/rpi2-port/Guide/Guide.tex @@ -346,7 +346,7 @@ \subsection{Using JTAG with the GDB debugger} One thing we might be particularly interested in is changing the value of a register. This can be done through the command \texttt{set \$r0 = 0x13}, where you can swap \texttt{r0} for the name of the register you want to change and \texttt{0x13} for another value. Then, execute the command \texttt{c} to continue when you have stopped at a breakpoint. When you are finished, execute \texttt{quit}. -To a limited degree, you can also use the Emacs UI to toggle breakpoints and other things. There are a gazillion useful GDB commands. If you want to learn more, you can type \texttt{help} at the \texttt{gdb} prompt. +To a limited degree, you can also use the Emacs UI to toggle breakpoints and other things. There are a gazillion useful GDB commands. If you want to learn more, you can type \texttt{help} at the \texttt{(gdb)} prompt. \bibliography{Guide}{} \bibliographystyle{acm}