1.1 --- a/stage2/entry.S Mon Apr 25 17:19:53 2016 +0200
1.2 +++ b/stage2/entry.S Mon Apr 25 21:56:49 2016 +0200
1.3 @@ -21,6 +21,7 @@
1.4 .extern interrupt_handler
1.5 .extern current_registers
1.6 .extern current_stack_pointer
1.7 +.extern _payload_end
1.8 .globl _tlb_entry
1.9 .globl _exc_entry
1.10 .globl _irq_entry
1.11 @@ -42,13 +43,15 @@
1.12 beqz $k1, _tlb_entry_direct
1.13 nop
1.14
1.15 - /* For addresses over 0x00080000... */
1.16 + /* For addresses beyond the relocated global object table... */
1.17
1.18 - li $k1, 0xfff80000
1.19 - and $k1, $k0, $k1
1.20 + lui $k1, %hi(_payload_end - 0x80000000)
1.21 + ori $k1, $k1, %lo(_payload_end - 0x80000000)
1.22 + sltu $k1, $k1, $k0
1.23 bnez $k1, _tlb_entry_direct
1.24 nop
1.25
1.26 +_tlb_entry_table:
1.27 /* Otherwise, load the page table entries. */
1.28
1.29 andi $k1, $k0, 0xff /* ASID */
2.1 --- a/stage2/stage2.ld Mon Apr 25 17:19:53 2016 +0200
2.2 +++ b/stage2/stage2.ld Mon Apr 25 21:56:49 2016 +0200
2.3 @@ -6,6 +6,10 @@
2.4 /* Program memory section. */
2.5
2.6 . = 0x81c00000;
2.7 +
2.8 + _payload_start = ABSOLUTE(.);
2.9 + _shared_start = ABSOLUTE(.);
2.10 +
2.11 .text2 : { *(.text*) }
2.12
2.13 . = ALIGN(4);
2.14 @@ -17,21 +21,33 @@
2.15 . = ALIGN(4);
2.16 .data : { *(.data*) *(.scommon*) *(.reginfo*) }
2.17
2.18 - _gp = ALIGN(16);
2.19 -
2.20 - _got_start = ABSOLUTE(.);
2.21 - .got : { *(.got*) }
2.22 - _got_end = ABSOLUTE(.);
2.23 -
2.24 - _gp_copy = ALIGN(16);
2.25 -
2.26 - _got_copy_start = ABSOLUTE(.);
2.27 - . += _got_end - _got_start;
2.28 - _got_copy_end = ABSOLUTE(.);
2.29 + _shared_end = ABSOLUTE(.);
2.30
2.31 . = ALIGN(4);
2.32 +
2.33 + _bss_start = ABSOLUTE(.);
2.34 +
2.35 .sbss : { *(.sbss*) }
2.36 .bss : { *(.bss*) }
2.37 . = ALIGN (4);
2.38 +
2.39 + _bss_end = ABSOLUTE(.);
2.40 +
2.41 + /* The global object table. */
2.42 +
2.43 + .got : ALIGN(4096) {
2.44 + _gp = ALIGN(16);
2.45 + _got_start = ABSOLUTE(.);
2.46 + *(.got*)
2.47 + }
2.48 + _got_end = ABSOLUTE(.);
2.49 +
2.50 + /* The relocated copy of the global object table. */
2.51 +
2.52 + .got_copy : ALIGN(4096) {
2.53 + _got_copy_start = ABSOLUTE(.);
2.54 + . += _got_end - _got_start - 1;
2.55 + }
2.56 + _got_copy_end = ABSOLUTE(.);
2.57 + _payload_end = ABSOLUTE(.);
2.58 }
2.59 -
3.1 --- a/stage2/tasks.c Mon Apr 25 17:19:53 2016 +0200
3.2 +++ b/stage2/tasks.c Mon Apr 25 21:56:49 2016 +0200
3.3 @@ -36,9 +36,16 @@
3.4 const u32 stack_size = 0x00002000;
3.5 const u32 pagesize = 4 * 1024;
3.6
3.7 -/* A reference to the unrelocated symbol table location. */
3.8 +/*
3.9 +References to the unrelocated symbol table and to the relocated version, both in
3.10 +their original locations.
3.11 +*/
3.12
3.13 -extern u32 _got_copy_start;
3.14 +extern u32 _got_start, _got_copy_start;
3.15 +
3.16 +/* Regions to be mapped directly. */
3.17 +
3.18 +extern u32 _shared_start, _shared_end;
3.19
3.20 /* Task management functions. */
3.21
3.22 @@ -56,7 +63,7 @@
3.23
3.24 void start_task(unsigned short task, void (*function)(), u32 args[], u8 nargs)
3.25 {
3.26 - u32 virtual, physical;
3.27 + u32 virtual, physical, address;
3.28
3.29 /*
3.30 Each task employs a stack at a multiple of the given start address in
3.31 @@ -68,6 +75,18 @@
3.32
3.33 init_page_table(page_table_start, virtual - pagesize * 2, physical - pagesize * 2, pagesize, 0x1e, task);
3.34
3.35 + /* Map shared pages. */
3.36 +
3.37 + for (address = (u32) &_shared_start; address < (u32) &_shared_end; address += pagesize * 2)
3.38 + {
3.39 + address = address & 0x7fffffff;
3.40 + init_page_table(page_table_start, address, address, pagesize, 0x1e, task);
3.41 + }
3.42 +
3.43 + /* Map the task's global object table to the relocated version. */
3.44 +
3.45 + init_page_table(page_table_start, (u32) &_got_start & 0x7fffffff, (u32) &_got_copy_start & 0x7fffffff, pagesize, 0x1e, task);
3.46 +
3.47 /*
3.48 Subtract from the stack pointer to prevent the called function from
3.49 reaching into unmapped memory.
3.50 @@ -80,7 +99,7 @@
3.51 return address.
3.52 */
3.53
3.54 - init_registers(registers[task], (u32) &_got_copy_start, function, args, nargs);
3.55 + init_registers(registers[task], (u32) &_got_start, function, args, nargs);
3.56 }
3.57
3.58 void start_task_now()