/*
 * Memory layout for stage 3
 * =========================
 *
 * General memory layout
 * ---------------------
 *
 * 0x0000-0x1fff	Lowcore
 * 0x2000-0x5fff	Memory allocation (heap)
 * 0x6000-0x8fff	free
 * 0x9000-0x9fff        Stage3 parameter
 * 0xa000-0xdfff        Stage3 code + data
 * 0xf000-0xffff        Stack
 */

#include "boot/loaders_layout.h"
#include "boot/s390.h"

SECTIONS
{
  . = 0x0;

  . = STAGE3_HEAP_ADDRESS;
  __heap_start = .;
  .heap : {
    . += STAGE3_HEAP_SIZE;
    ASSERT(__heap_stop - __heap_start == STAGE3_HEAP_SIZE,
           "Heap section doesn't conform to the described memory layout");
  }
  __heap_stop = .;

  /* stage 3 parameter */
  . = STAGE3_PARAMS_ADDRESS;
  _stage3_parms = .;

  . = STAGE3_ENTRY;
  .text : {
    *(.text.start)
    *(.text .text.*)
  }
  __ex_table_start = .;
  .ex_table : { *(.ex_table) }
  __ex_table_stop = .;

  __bss_start = .;
  .bss : { *(.bss .bss.*) }
  __bss_stop = .;
  .rodata : {*(.rodata .rodata.*) }
  .data : { *(.data .data.*) }

#define SB_TRAILER_SIZE 32
  /* Trailer needed for Secure Boot */
  . = COMMAND_LINE_EXTRA - SB_TRAILER_SIZE;
  .sb.trailer : {
    QUAD(0x0000c00000000000)
    QUAD(STAGE3_ENTRY + PSW_LOAD)
    QUAD(STAGE3_ENTRY)
    QUAD(0x000000207a49504c)
  }
  ASSERT(SIZEOF(.sb.trailer) == SB_TRAILER_SIZE, "Invalid .sb.trailer size")

  . = COMMAND_LINE_EXTRA;
  .cmdline_extra : {
    . += COMMAND_LINE_EXTRA_SIZE;
  }

  . = STAGE3_STACK_ADDRESS;
  __stack_start = .;
  .stack : {
    . += STAGE3_STACK_SIZE;
    ASSERT(__stack_end - __stack_start == STAGE3_STACK_SIZE,
           "Stack section doesn't conform to the described memory layout");
  }
  __stack_end = .;

  /* Sections to be discarded */
  /DISCARD/ : {
    *(.eh_frame)
    *(.interp)
    *(.note.GNU-stack)
    *(.note.package)
  }
}
