[Sound-open-firmware] [PATCH] platform: hsw: Add platform support drivers for haswell and broadwell

Liam Girdwood liam.r.girdwood at linux.intel.com
Mon Jan 22 12:33:24 CET 2018


Add platform support drivers an initialisation for Haswell and Broadwell.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/platform/haswell/Makefile.am    |  16 ++
 src/platform/haswell/broadwell.x.in | 508 ++++++++++++++++++++++++++++++++++++
 src/platform/haswell/clk.c          | 210 +++++++++++++++
 src/platform/haswell/dai.c          |  89 +++++++
 src/platform/haswell/dma.c          | 137 ++++++++++
 src/platform/haswell/haswell.x.in   | 508 ++++++++++++++++++++++++++++++++++++
 src/platform/haswell/platform.c     | 249 ++++++++++++++++++
 src/platform/haswell/timer.c        | 105 ++++++++
 8 files changed, 1822 insertions(+)
 create mode 100644 src/platform/haswell/Makefile.am
 create mode 100755 src/platform/haswell/broadwell.x.in
 create mode 100644 src/platform/haswell/clk.c
 create mode 100644 src/platform/haswell/dai.c
 create mode 100644 src/platform/haswell/dma.c
 create mode 100755 src/platform/haswell/haswell.x.in
 create mode 100644 src/platform/haswell/platform.c
 create mode 100644 src/platform/haswell/timer.c

diff --git a/src/platform/haswell/Makefile.am b/src/platform/haswell/Makefile.am
new file mode 100644
index 0000000..bf9d40a
--- /dev/null
+++ b/src/platform/haswell/Makefile.am
@@ -0,0 +1,16 @@
+SUBDIRS = include
+
+noinst_LIBRARIES = libplatform.a
+
+libplatform_a_SOURCES = \
+	platform.c \
+	dai.c \
+	dma.c \
+	clk.c \
+	timer.c
+
+libplatform_a_CFLAGS = \
+	$(ARCH_CFLAGS) \
+	$(ARCH_INCDIR) \
+	$(REEF_INCDIR) \
+	$(PLATFORM_INCDIR)
diff --git a/src/platform/haswell/broadwell.x.in b/src/platform/haswell/broadwell.x.in
new file mode 100755
index 0000000..51a573c
--- /dev/null
+++ b/src/platform/haswell/broadwell.x.in
@@ -0,0 +1,508 @@
+/*
+ * Linker Script for Broadwell.
+ *
+ * This script is run through the GNU C preprocessor to align the memory
+ * offsets with headers.
+ *
+ * Use spaces for formatting as cpp ignore tab sizes.
+ */
+
+#include <platform/memory.h>
+#include <xtensa/config/core-isa.h>
+
+OUTPUT_ARCH(xtensa)
+
+MEMORY
+{
+  vector_reset_text :
+        org = XCHAL_RESET_VECTOR0_PADDR,
+        len = REEF_MEM_RESET_TEXT_SIZE
+  vector_reset_lit :
+        org = XCHAL_RESET_VECTOR0_PADDR + REEF_MEM_RESET_TEXT_SIZE,
+        len = REEF_MEM_RESET_LIT_SIZE
+  vector_base_text :
+       	org = XCHAL_VECBASE_RESET_PADDR,
+        len = REEF_MEM_VECBASE_LIT_SIZE
+  vector_int2_lit :
+       	org = XCHAL_INTLEVEL2_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int2_text :
+        org = XCHAL_INTLEVEL2_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int3_lit :
+       	org = XCHAL_INTLEVEL3_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int3_text :
+       	org = XCHAL_INTLEVEL3_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int4_lit :
+       	org = XCHAL_INTLEVEL4_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int4_text :
+       	org = XCHAL_INTLEVEL4_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int5_lit :
+       	org = XCHAL_INTLEVEL5_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE, 
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int5_text :
+       	org = XCHAL_INTLEVEL5_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int6_lit :
+       	org = XCHAL_INTLEVEL6_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int6_text :
+       	org = XCHAL_INTLEVEL6_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int7_lit :
+       	org = XCHAL_INTLEVEL7_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int7_text :
+       	org = XCHAL_INTLEVEL7_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_kernel_lit :
+       	org = XCHAL_KERNEL_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_kernel_text :
+       	org = XCHAL_KERNEL_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_user_lit :
+       	org = XCHAL_USER_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_user_text :
+       	org = XCHAL_USER_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_double_lit :
+       	org = XCHAL_DOUBLEEXC_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_double_text :
+       	org = XCHAL_DOUBLEEXC_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  reef_text_start :
+       	org = XCHAL_NMI_VECTOR_VADDR + REEF_MEM_VECT_SIZE,
+        len = (IRAM_BASE + IRAM_SIZE) - (XCHAL_NMI_VECTOR_VADDR + REEF_MEM_VECT_SIZE)
+  reef_data_ro :
+       	org = DRAM0_BASE,
+        len = REEF_MEM_RO_SIZE
+  reef_data :
+       	org = DRAM0_BASE + REEF_MEM_RO_SIZE,
+        len = HEAP_SYSTEM_BASE - (DRAM0_BASE + REEF_MEM_RO_SIZE)
+  system_heap :
+        org = HEAP_SYSTEM_BASE,
+        len = HEAP_SYSTEM_SIZE
+  runtime_heap :
+        org = HEAP_RUNTIME_BASE,
+        len = HEAP_RUNTIME_SIZE
+  buffer_heap :
+        org = HEAP_BUFFER_BASE,
+        len = HEAP_BUFFER_SIZE
+  reef_stack :
+        org = REEF_STACK_END,
+        len = REEF_STACK_BASE - REEF_STACK_END
+}
+
+PHDRS
+{
+  vector_reset_text_phdr PT_LOAD;
+  vector_reset_lit_phdr PT_LOAD;
+  vector_base_text_phdr PT_LOAD;
+  vector_base_lit_phdr PT_LOAD;
+  vector_int2_text_phdr PT_LOAD;
+  vector_int2_lit_phdr PT_LOAD;
+  vector_int3_text_phdr PT_LOAD;
+  vector_int3_lit_phdr PT_LOAD;
+  vector_int4_text_phdr PT_LOAD;
+  vector_int4_lit_phdr PT_LOAD;
+  vector_int5_text_phdr PT_LOAD;
+  vector_int5_lit_phdr PT_LOAD;
+  vector_int6_text_phdr PT_LOAD;
+  vector_int6_lit_phdr PT_LOAD;
+  vector_int7_text_phdr PT_LOAD;
+  vector_int7_lit_phdr PT_LOAD;
+  vector_kernel_text_phdr PT_LOAD;
+  vector_kernel_lit_phdr PT_LOAD;
+  vector_user_text_phdr PT_LOAD;
+  vector_user_lit_phdr PT_LOAD;
+  vector_double_text_phdr PT_LOAD;
+  vector_double_lit_phdr PT_LOAD;
+  reef_text_start_phdr PT_LOAD;
+  reef_data_ro_phdr PT_LOAD;
+  reef_data_phdr PT_LOAD;
+  reef_data_bss_phdr PT_LOAD;
+  system_heap_phdr PT_LOAD;
+  runtime_heap_phdr PT_LOAD;
+  buffer_heap_phdr PT_LOAD;
+  reef_stack_phdr PT_LOAD;
+}
+
+/*  Default entry point:  */
+ENTRY(_ResetVector)
+_rom_store_table = 0;
+
+/* ABI0 does not use Window base */
+PROVIDE(_memmap_vecbase_reset = XCHAL_VECBASE_RESET_PADDR);
+
+/* Various memory-map dependent cache attribute settings: */
+_memmap_cacheattr_wb_base = 0x44024000;
+_memmap_cacheattr_wt_base = 0x11021000;
+_memmap_cacheattr_bp_base = 0x22022000;
+_memmap_cacheattr_unused_mask = 0x00F00FFF;
+_memmap_cacheattr_wb_trapnull = 0x4422422F;
+_memmap_cacheattr_wba_trapnull = 0x4422422F;
+_memmap_cacheattr_wbna_trapnull = 0x25222222;
+_memmap_cacheattr_wt_trapnull = 0x1122122F;
+_memmap_cacheattr_bp_trapnull = 0x2222222F;
+_memmap_cacheattr_wb_strict = 0x44F24FFF;
+_memmap_cacheattr_wt_strict = 0x11F21FFF;
+_memmap_cacheattr_bp_strict = 0x22F22FFF;
+_memmap_cacheattr_wb_allvalid = 0x44224222;
+_memmap_cacheattr_wt_allvalid = 0x11221222;
+_memmap_cacheattr_bp_allvalid = 0x22222222;
+PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull);
+
+SECTIONS
+{
+  .ResetVector.text : ALIGN(4)
+  {
+    _ResetVector_text_start = ABSOLUTE(.);
+    KEEP (*(.ResetVector.text))
+    _ResetVector_text_end = ABSOLUTE(.);
+  } >vector_reset_text :vector_reset_text_phdr
+
+  .ResetVector.literal : ALIGN(4)
+  {
+    _ResetVector_literal_start = ABSOLUTE(.);
+    *(.ResetVector.literal)
+    _ResetVector_literal_end = ABSOLUTE(.);
+  } >vector_reset_lit :vector_reset_lit_phdr
+
+  .WindowVectors.text : ALIGN(4)
+  {
+    _WindowVectors_text_start = ABSOLUTE(.);
+    KEEP (*(.WindowVectors.text))
+    _WindowVectors_text_end = ABSOLUTE(.);
+  } >vector_base_text :vector_base_text_phdr
+
+  .Level2InterruptVector.literal : ALIGN(4)
+  {
+    _Level2InterruptVector_literal_start = ABSOLUTE(.);
+    *(.Level2InterruptVector.literal)
+    _Level2InterruptVector_literal_end = ABSOLUTE(.);
+  } >vector_int2_lit :vector_int2_lit_phdr
+
+  .Level2InterruptVector.text : ALIGN(4)
+  {
+    _Level2InterruptVector_text_start = ABSOLUTE(.);
+    KEEP (*(.Level2InterruptVector.text))
+    _Level2InterruptVector_text_end = ABSOLUTE(.);
+  } >vector_int2_text :vector_int2_text_phdr
+
+  .Level3InterruptVector.literal : ALIGN(4)
+  {
+    _Level3InterruptVector_literal_start = ABSOLUTE(.);
+    *(.Level3InterruptVector.literal)
+    _Level3InterruptVector_literal_end = ABSOLUTE(.);
+  } >vector_int3_lit :vector_int3_lit_phdr
+
+  .Level3InterruptVector.text : ALIGN(4)
+  {
+    _Level3InterruptVector_text_start = ABSOLUTE(.);
+    KEEP (*(.Level3InterruptVector.text))
+    _Level3InterruptVector_text_end = ABSOLUTE(.);
+  } >vector_int3_text :vector_int3_text_phdr
+
+  .Level4InterruptVector.literal : ALIGN(4)
+  {
+    _Level4InterruptVector_literal_start = ABSOLUTE(.);
+    *(.Level4InterruptVector.literal)
+    _Level4InterruptVector_literal_end = ABSOLUTE(.);
+  } >vector_int4_lit :vector_int4_lit_phdr
+
+  .Level4InterruptVector.text : ALIGN(4)
+  {
+    _Level4InterruptVector_text_start = ABSOLUTE(.);
+    KEEP (*(.Level4InterruptVector.text))
+    _Level4InterruptVector_text_end = ABSOLUTE(.);
+  } >vector_int4_text :vector_int4_text_phdr
+
+  .Level5InterruptVector.literal : ALIGN(4)
+  {
+    _Level5InterruptVector_literal_start = ABSOLUTE(.);
+    *(.Level5InterruptVector.literal)
+    _Level5InterruptVector_literal_end = ABSOLUTE(.);
+  } >vector_int5_lit :vector_int5_lit_phdr
+
+  .Level5InterruptVector.text : ALIGN(4)
+  {
+    _Level5InterruptVector_text_start = ABSOLUTE(.);
+    KEEP (*(.Level5InterruptVector.text))
+    _Level5InterruptVector_text_end = ABSOLUTE(.);
+  } >vector_int5_text :vector_int5_text_phdr
+
+  .DebugExceptionVector.literal : ALIGN(4)
+  {
+    _DebugExceptionVector_literal_start = ABSOLUTE(.);
+    *(.DebugExceptionVector.literal)
+    _DebugExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_int6_lit :vector_int6_lit_phdr
+
+  .DebugExceptionVector.text : ALIGN(4)
+  {
+    _DebugExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.DebugExceptionVector.text))
+    _DebugExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_int6_text :vector_int6_text_phdr
+
+  .NMIExceptionVector.literal : ALIGN(4)
+  {
+    _NMIExceptionVector_literal_start = ABSOLUTE(.);
+    *(.NMIExceptionVector.literal)
+    _NMIExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_int7_lit :vector_int7_lit_phdr
+
+  .NMIExceptionVector.text : ALIGN(4)
+  {
+    _NMIExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.NMIExceptionVector.text))
+    _NMIExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_int7_text :vector_int7_text_phdr
+
+  .KernelExceptionVector.literal : ALIGN(4)
+  {
+    _KernelExceptionVector_literal_start = ABSOLUTE(.);
+    *(.KernelExceptionVector.literal)
+    _KernelExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_kernel_lit :vector_kernel_lit_phdr
+
+  .KernelExceptionVector.text : ALIGN(4)
+  {
+    _KernelExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.KernelExceptionVector.text))
+    _KernelExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_kernel_text :vector_kernel_text_phdr
+
+  .UserExceptionVector.literal : ALIGN(4)
+  {
+    _UserExceptionVector_literal_start = ABSOLUTE(.);
+    *(.UserExceptionVector.literal)
+    _UserExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_user_lit :vector_user_lit_phdr
+
+  .UserExceptionVector.text : ALIGN(4)
+  {
+    _UserExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.UserExceptionVector.text))
+    _UserExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_user_text :vector_user_text_phdr
+
+  .DoubleExceptionVector.literal : ALIGN(4)
+  {
+    _DoubleExceptionVector_literal_start = ABSOLUTE(.);
+    *(.DoubleExceptionVector.literal)
+    _DoubleExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_double_lit :vector_double_lit_phdr
+
+  .DoubleExceptionVector.text : ALIGN(4)
+  {
+    _DoubleExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.DoubleExceptionVector.text))
+    _DoubleExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_double_text :vector_double_text_phdr
+
+  .text : ALIGN(4)
+  {
+    _stext = .;
+    _text_start = ABSOLUTE(.);
+    *(.entry.text)
+    *(.init.literal)
+    KEEP(*(.init))
+    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
+    *(.fini.literal)
+    KEEP(*(.fini))
+    *(.gnu.version)
+    _text_end = ABSOLUTE(.);
+    _etext = .;
+  } >reef_text_start :reef_text_start_phdr
+
+  .reset.rodata : ALIGN(4)
+  {
+    _reset_rodata_start = ABSOLUTE(.);
+    *(.reset.rodata)
+    _reset_rodata_end = ABSOLUTE(.);
+  } >reef_data_ro :reef_data_ro_phdr
+
+  .rodata : ALIGN(4)
+  {
+    _rodata_start = ABSOLUTE(.);
+    *(.rodata)
+    *(.rodata.*)
+    *(.gnu.linkonce.r.*)
+    *(.rodata1)
+    __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
+    KEEP (*(.xt_except_table))
+    KEEP (*(.gcc_except_table))
+    *(.gnu.linkonce.e.*)
+    *(.gnu.version_r)
+    KEEP (*(.eh_frame))
+    /*  C++ constructor and destructor tables, properly ordered:  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+    /*  C++ exception handlers table:  */
+    __XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
+    *(.xt_except_desc)
+    *(.gnu.linkonce.h.*)
+    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
+    *(.xt_except_desc_end)
+    *(.dynamic)
+    *(.gnu.version_d)
+    . = ALIGN(4);		/* this table MUST be 4-byte aligned */
+    _bss_table_start = ABSOLUTE(.);
+    LONG(_bss_start)
+    LONG(_bss_end)
+    _bss_table_end = ABSOLUTE(.);
+    _rodata_end = ABSOLUTE(.);
+  } >reef_data :reef_data_phdr
+
+  .data : ALIGN(4)
+  {
+    _data_start = ABSOLUTE(.);
+    *(.data)
+    *(.data.*)
+    *(.gnu.linkonce.d.*)
+    KEEP(*(.gnu.linkonce.d.*personality*))
+    *(.data1)
+    *(.sdata)
+    *(.sdata.*)
+    *(.gnu.linkonce.s.*)
+    *(.sdata2)
+    *(.sdata2.*)
+    *(.gnu.linkonce.s2.*)
+    KEEP(*(.jcr))
+    _data_end = ABSOLUTE(.);
+  } >reef_data :reef_data_phdr
+
+  .lit4 : ALIGN(4)
+  {
+    _lit4_start = ABSOLUTE(.);
+    *(*.lit4)
+    *(.lit4.*)
+    *(.gnu.linkonce.lit4.*)
+    _lit4_end = ABSOLUTE(.);
+  } >reef_data :reef_data_phdr
+
+  .bss (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (8);
+    _bss_start = ABSOLUTE(.);
+    *(.dynsbss)
+    *(.sbss)
+    *(.sbss.*)
+    *(.gnu.linkonce.sb.*)
+    *(.scommon)
+    *(.sbss2)
+    *(.sbss2.*)
+    *(.gnu.linkonce.sb2.*)
+    *(.dynbss)
+    *(.bss)
+    *(.bss.*)
+    *(.gnu.linkonce.b.*)
+    *(COMMON)
+    . = ALIGN (8);
+    _bss_end = ABSOLUTE(.);
+  } >reef_data :reef_data_bss_phdr
+
+  /* stack */
+  _end = REEF_STACK_END;
+  PROVIDE(end = REEF_STACK_END);
+  _stack_sentry = REEF_STACK_END;
+  __stack = REEF_STACK_BASE;
+
+  .debug  0 :  { *(.debug) }
+  .line  0 :  { *(.line) }
+  .debug_srcinfo  0 :  { *(.debug_srcinfo) }
+  .debug_sfnames  0 :  { *(.debug_sfnames) }
+  .debug_aranges  0 :  { *(.debug_aranges) }
+  .debug_pubnames  0 :  { *(.debug_pubnames) }
+  .debug_info  0 :  { *(.debug_info) }
+  .debug_abbrev  0 :  { *(.debug_abbrev) }
+  .debug_line  0 :  { *(.debug_line) }
+  .debug_frame  0 :  { *(.debug_frame) }
+  .debug_str  0 :  { *(.debug_str) }
+  .debug_loc  0 :  { *(.debug_loc) }
+  .debug_macinfo  0 :  { *(.debug_macinfo) }
+  .debug_weaknames  0 :  { *(.debug_weaknames) }
+  .debug_funcnames  0 :  { *(.debug_funcnames) }
+  .debug_typenames  0 :  { *(.debug_typenames) }
+  .debug_varnames  0 :  { *(.debug_varnames) }
+
+  .xt.insn 0 :
+  {
+    KEEP (*(.xt.insn))
+    KEEP (*(.gnu.linkonce.x.*))
+  }
+  .xt.prop 0 :
+  {
+    KEEP (*(.xt.prop))
+    KEEP (*(.xt.prop.*))
+    KEEP (*(.gnu.linkonce.prop.*))
+  }
+  .xt.lit 0 :
+  {
+    KEEP (*(.xt.lit))
+    KEEP (*(.xt.lit.*))
+    KEEP (*(.gnu.linkonce.p.*))
+  }
+  .xt.profile_range 0 :
+  {
+    KEEP (*(.xt.profile_range))
+    KEEP (*(.gnu.linkonce.profile_range.*))
+  }
+  .xt.profile_ranges 0 :
+  {
+    KEEP (*(.xt.profile_ranges))
+    KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
+  }
+  .xt.profile_files 0 :
+  {
+    KEEP (*(.xt.profile_files))
+    KEEP (*(.gnu.linkonce.xt.profile_files.*))
+  }
+
+  .system_heap (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (32);
+    _system_heap_start = ABSOLUTE(.);
+    . = . + HEAP_SYSTEM_SIZE;
+    _system_heap_end = ABSOLUTE(.);
+  } >system_heap :system_heap_phdr
+
+  .runtime_heap (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (32);
+    _runtime_heap_start = ABSOLUTE(.);
+    . = . + HEAP_RUNTIME_SIZE;
+    _runtime_heap_end = ABSOLUTE(.);
+  } >runtime_heap :runtime_heap_phdr
+
+  .buffer_heap (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (32);
+    _system_heap_start = ABSOLUTE(.);
+    . = . + HEAP_BUFFER_SIZE;
+    _system_heap_end = ABSOLUTE(.);
+  } >buffer_heap :buffer_heap_phdr
+
+  .reef_stack (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (4096);
+    _reef_stack_start = ABSOLUTE(.);
+    . = . + REEF_STACK_SIZE;
+    _reef_stack_end = ABSOLUTE(.);
+  } >reef_stack :reef_stack_phdr
+}
+
diff --git a/src/platform/haswell/clk.c b/src/platform/haswell/clk.c
new file mode 100644
index 0000000..0d4449d
--- /dev/null
+++ b/src/platform/haswell/clk.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <reef/clock.h>
+#include <reef/io.h>
+#include <reef/reef.h>
+#include <reef/list.h>
+#include <reef/alloc.h>
+#include <reef/notifier.h>
+#include <reef/lock.h>
+#include <platform/clk.h>
+#include <platform/shim.h>
+#include <platform/timer.h>
+#include <config.h>
+#include <stdint.h>
+#include <limits.h>
+
+#define NUM_CLOCKS	2
+
+struct clk_data {
+	uint32_t freq;
+	uint32_t ticks_per_usec;
+	spinlock_t lock;
+};
+
+struct clk_pdata {
+	struct clk_data clk[NUM_CLOCKS];
+};
+
+struct freq_table {
+	uint32_t freq;
+	uint32_t ticks_per_usec;
+	uint32_t fabric;
+	uint32_t enc;
+};
+
+static struct clk_pdata *clk_pdata;
+
+/* increasing frequency order */
+static const struct freq_table cpu_freq[] = {
+	{32000000, 80, 32000000, 0x6},
+	{80000000, 80, 80000000, 0x2},
+	{160000000, 160, 80000000, 0x1},
+	{320000000, 320, 160000000, 0x4},/* default */
+	{320000000, 320, 80000000, 0x0},
+	{160000000, 160, 160000000, 0x5},
+};
+
+static const struct freq_table ssp_freq[] = {
+	{24000000, 24, 0, 0},	/* default */
+};
+
+#define CPU_DEFAULT_IDX		3
+#define SSP_DEFAULT_IDX		0
+
+static inline uint32_t get_freq(const struct freq_table *table, int size,
+	unsigned int hz)
+{
+	uint32_t i;
+
+	/* find lowest available frequency that is >= requested Hz */
+	for (i = 0; i < size; i++) {
+		if (hz <= table[i].freq)
+			return i;
+	}
+
+	/* not found, so return max frequency */
+	return size - 1;
+}
+
+void clock_enable(int clock)
+{
+	switch (clock) {
+	case CLK_CPU:
+		break;
+	case CLK_SSP:
+	default:
+		break;
+	}
+}
+
+void clock_disable(int clock)
+{
+	switch (clock) {
+	case CLK_CPU:
+		break;
+	case CLK_SSP:
+	default:
+		break;
+	}
+}
+
+uint32_t clock_set_freq(int clock, uint32_t hz)
+{
+	struct clock_notify_data notify_data;
+	uint32_t idx;
+	uint32_t flags;
+
+	notify_data.old_freq = clk_pdata->clk[clock].freq;
+	notify_data.old_ticks_per_usec = clk_pdata->clk[clock].ticks_per_usec;
+
+	/* atomic context for chaining clocks */
+	spin_lock_irq(&clk_pdata->clk[clock].lock, flags);
+
+	switch (clock) {
+	case CLK_CPU:
+
+		/* get nearest frequency that is >= requested Hz */
+		idx = get_freq(cpu_freq, ARRAY_SIZE(cpu_freq), hz);
+		notify_data.freq = cpu_freq[idx].freq;
+
+		/* tell anyone interested we are about to change CPU freq */
+		notifier_event(NOTIFIER_ID_CPU_FREQ, CLOCK_NOTIFY_PRE,
+			&notify_data);
+
+		/* set CPU frequency request for CCU */
+		io_reg_update_bits(SHIM_BASE + SHIM_CSR,
+						SHIM_CSR_DCS_MASK,
+						SHIM_CSR_DCS(cpu_freq[idx].enc));
+
+		/* tell anyone interested we have now changed CPU freq */
+		notifier_event(NOTIFIER_ID_CPU_FREQ, CLOCK_NOTIFY_POST,
+			&notify_data);
+		break;
+	case CLK_SSP:
+	default:
+		break;
+	}
+
+	spin_unlock_irq(&clk_pdata->clk[clock].lock, flags);
+	return clk_pdata->clk[clock].freq;
+}
+
+uint32_t clock_get_freq(int clock)
+{
+	return clk_pdata->clk[clock].freq;
+}
+
+uint64_t clock_us_to_ticks(int clock, uint64_t us)
+{
+	return clk_pdata->clk[clock].ticks_per_usec * us;
+}
+
+uint64_t clock_time_elapsed(int clock, uint64_t previous, uint64_t *current)
+{
+	uint64_t _current;
+
+	// TODO: change timer APIs to clk APIs ??
+	switch (clock) {
+	case CLK_CPU:
+		_current = arch_timer_get_system(NULL);
+		break;
+	case CLK_SSP:
+		_current = platform_timer_get(platform_timer);
+		break;
+	default:
+		return 0;
+	}
+
+	*current = _current;
+	if (_current >= previous)
+		return (_current - previous) /
+			clk_pdata->clk[clock].ticks_per_usec;
+	else
+		return (_current + (ULONG_LONG_MAX - previous)) /
+			clk_pdata->clk[clock].ticks_per_usec;
+}
+
+void init_platform_clocks(void)
+{
+	clk_pdata = rmalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*clk_pdata));
+
+	spinlock_init(&clk_pdata->clk[0].lock);
+	spinlock_init(&clk_pdata->clk[1].lock);
+
+	/* set defaults */
+	clk_pdata->clk[CLK_CPU].freq = cpu_freq[CPU_DEFAULT_IDX].freq;
+	clk_pdata->clk[CLK_CPU].ticks_per_usec =
+			cpu_freq[CPU_DEFAULT_IDX].ticks_per_usec;
+	clk_pdata->clk[CLK_SSP].freq = ssp_freq[SSP_DEFAULT_IDX].freq;
+	clk_pdata->clk[CLK_SSP].ticks_per_usec =
+			ssp_freq[SSP_DEFAULT_IDX].ticks_per_usec;
+}
diff --git a/src/platform/haswell/dai.c b/src/platform/haswell/dai.c
new file mode 100644
index 0000000..4a05e6a
--- /dev/null
+++ b/src/platform/haswell/dai.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <reef/reef.h>
+#include <reef/dai.h>
+#include <reef/ssp.h>
+#include <reef/stream.h>
+#include <reef/audio/component.h>
+#include <platform/memory.h>
+#include <platform/interrupt.h>
+#include <platform/dma.h>
+#include <stdint.h>
+#include <string.h>
+#include <config.h>
+
+static struct dai ssp[2] = {
+{
+	.type = SOF_DAI_INTEL_SSP,
+	.index = 0,
+	.plat_data = {
+		.base		= SSP0_BASE,
+		.irq		= IRQ_NUM_EXT_SSP0,
+		.fifo[SOF_IPC_STREAM_PLAYBACK] = {
+			.offset		= SSP0_BASE + SSDR,
+			.handshake	= DMA_HANDSHAKE_SSP0_TX,
+		},
+		.fifo[SOF_IPC_STREAM_CAPTURE] = {
+			.offset		= SSP0_BASE + SSDR,
+			.handshake	= DMA_HANDSHAKE_SSP0_RX,
+		}
+	},
+	.ops		= &ssp_ops,
+},
+{
+	.type = SOF_DAI_INTEL_SSP,
+	.index = 1,
+	.plat_data = {
+		.base		= SSP1_BASE,
+		.irq		= IRQ_NUM_EXT_SSP1,
+		.fifo[SOF_IPC_STREAM_PLAYBACK] = {
+			.offset		= SSP1_BASE + SSDR,
+			.handshake	= DMA_HANDSHAKE_SSP1_TX,
+		},
+		.fifo[SOF_IPC_STREAM_CAPTURE] = {
+			.offset		= SSP1_BASE + SSDR,
+			.handshake	= DMA_HANDSHAKE_SSP1_RX,
+		}
+	},
+	.ops		= &ssp_ops,
+}};
+
+struct dai *dai_get(uint32_t type, uint32_t index)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ssp); i++) {
+		if (ssp[i].type == type && ssp[i].index == index)
+			return &ssp[i];
+	}
+
+	return NULL;
+}
diff --git a/src/platform/haswell/dma.c b/src/platform/haswell/dma.c
new file mode 100644
index 0000000..92cd5db
--- /dev/null
+++ b/src/platform/haswell/dma.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <reef/dma.h>
+#include <reef/dw-dma.h>
+#include <platform/memory.h>
+#include <platform/interrupt.h>
+#include <platform/dma.h>
+#include <stdint.h>
+#include <string.h>
+
+static struct dw_drv_plat_data dmac0 = {
+	.chan[0] = {
+		.class	= 6,
+		.weight = 0,
+	},
+	.chan[1] = {
+		.class	= 6,
+		.weight = 0,
+	},
+	.chan[2] = {
+		.class	= 6,
+		.weight = 0,
+	},
+	.chan[3] = {
+		.class	= 6,
+		.weight = 0,
+	},
+	.chan[4] = {
+		.class	= 6,
+		.weight = 0,
+	},
+	.chan[5] = {
+		.class	= 6,
+		.weight = 0,
+	},
+	.chan[6] = {
+		.class	= 6,
+		.weight = 0,
+	},
+	.chan[7] = {
+		.class	= 6,
+		.weight = 0,
+	},
+};
+
+static struct dw_drv_plat_data dmac1 = {
+	.chan[0] = {
+		.class	= 7,
+		.weight = 0,
+	},
+	.chan[1] = {
+		.class	= 7,
+		.weight = 0,
+	},
+	.chan[2] = {
+		.class	= 7,
+		.weight = 0,
+	},
+	.chan[3] = {
+		.class	= 7,
+		.weight = 0,
+	},
+	.chan[4] = {
+		.class	= 7,
+		.weight = 0,
+	},
+	.chan[5] = {
+		.class	= 7,
+		.weight = 0,
+	},
+	.chan[6] = {
+		.class	= 7,
+		.weight = 0,
+	},
+	.chan[7] = {
+		.class	= 7,
+		.weight = 0,
+	},
+};
+
+static struct dma dma[] = {
+{
+	.plat_data = {
+		.base		= DMA0_BASE,
+		.irq		= IRQ_NUM_EXT_DMAC0,
+		.drv_plat_data	= &dmac0,
+	},
+	.ops		= &dw_dma_ops,
+},
+{
+	.plat_data = {
+		.base		= DMA1_BASE,
+		.irq		= IRQ_NUM_EXT_DMAC1,
+		.drv_plat_data	= &dmac1,
+	},
+	.ops		= &dw_dma_ops,
+},};
+
+struct dma *dma_get(int dmac_id)
+{
+	switch (dmac_id) {
+	case DMA_ID_DMAC0:
+		return &dma[0];
+	case DMA_ID_DMAC1:
+		return &dma[1];
+	default:
+		return NULL;
+	}
+}
diff --git a/src/platform/haswell/haswell.x.in b/src/platform/haswell/haswell.x.in
new file mode 100755
index 0000000..add3eed
--- /dev/null
+++ b/src/platform/haswell/haswell.x.in
@@ -0,0 +1,508 @@
+/*
+ * Linker Script for Baytrail.
+ *
+ * This script is run through the GNU C preprocessor to align the memory
+ * offsets with headers.
+ *
+ * Use spaces for formatting as cpp ignore tab sizes.
+ */
+
+#include <platform/memory.h>
+#include <xtensa/config/core-isa.h>
+
+OUTPUT_ARCH(xtensa)
+
+MEMORY
+{
+  vector_reset_text :
+        org = XCHAL_RESET_VECTOR0_PADDR,
+        len = REEF_MEM_RESET_TEXT_SIZE
+  vector_reset_lit :
+        org = XCHAL_RESET_VECTOR0_PADDR + REEF_MEM_RESET_TEXT_SIZE,
+        len = REEF_MEM_RESET_LIT_SIZE
+  vector_base_text :
+       	org = XCHAL_VECBASE_RESET_PADDR,
+        len = REEF_MEM_VECBASE_LIT_SIZE
+  vector_int2_lit :
+       	org = XCHAL_INTLEVEL2_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int2_text :
+        org = XCHAL_INTLEVEL2_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int3_lit :
+       	org = XCHAL_INTLEVEL3_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int3_text :
+       	org = XCHAL_INTLEVEL3_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int4_lit :
+       	org = XCHAL_INTLEVEL4_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int4_text :
+       	org = XCHAL_INTLEVEL4_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int5_lit :
+       	org = XCHAL_INTLEVEL5_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE, 
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int5_text :
+       	org = XCHAL_INTLEVEL5_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int6_lit :
+       	org = XCHAL_INTLEVEL6_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int6_text :
+       	org = XCHAL_INTLEVEL6_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_int7_lit :
+       	org = XCHAL_INTLEVEL7_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_int7_text :
+       	org = XCHAL_INTLEVEL7_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_kernel_lit :
+       	org = XCHAL_KERNEL_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_kernel_text :
+       	org = XCHAL_KERNEL_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_user_lit :
+       	org = XCHAL_USER_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_user_text :
+       	org = XCHAL_USER_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  vector_double_lit :
+       	org = XCHAL_DOUBLEEXC_VECTOR_PADDR - REEF_MEM_VECT_LIT_SIZE,
+        len = REEF_MEM_VECT_LIT_SIZE
+  vector_double_text :
+       	org = XCHAL_DOUBLEEXC_VECTOR_PADDR,
+        len = REEF_MEM_VECT_TEXT_SIZE
+  reef_text_start :
+       	org = XCHAL_NMI_VECTOR_VADDR + REEF_MEM_VECT_SIZE,
+        len = (IRAM_BASE + IRAM_SIZE) - (XCHAL_NMI_VECTOR_VADDR + REEF_MEM_VECT_SIZE)
+  reef_data_ro :
+       	org = DRAM0_BASE,
+        len = REEF_MEM_RO_SIZE
+  reef_data :
+       	org = DRAM0_BASE + REEF_MEM_RO_SIZE,
+        len = HEAP_SYSTEM_BASE - (DRAM0_BASE + REEF_MEM_RO_SIZE)
+  system_heap :
+        org = HEAP_SYSTEM_BASE,
+        len = HEAP_SYSTEM_SIZE
+  runtime_heap :
+        org = HEAP_RUNTIME_BASE,
+        len = HEAP_RUNTIME_SIZE
+  buffer_heap :
+        org = HEAP_BUFFER_BASE,
+        len = HEAP_BUFFER_SIZE
+  reef_stack :
+        org = REEF_STACK_END,
+        len = REEF_STACK_BASE - REEF_STACK_END
+}
+
+PHDRS
+{
+  vector_reset_text_phdr PT_LOAD;
+  vector_reset_lit_phdr PT_LOAD;
+  vector_base_text_phdr PT_LOAD;
+  vector_base_lit_phdr PT_LOAD;
+  vector_int2_text_phdr PT_LOAD;
+  vector_int2_lit_phdr PT_LOAD;
+  vector_int3_text_phdr PT_LOAD;
+  vector_int3_lit_phdr PT_LOAD;
+  vector_int4_text_phdr PT_LOAD;
+  vector_int4_lit_phdr PT_LOAD;
+  vector_int5_text_phdr PT_LOAD;
+  vector_int5_lit_phdr PT_LOAD;
+  vector_int6_text_phdr PT_LOAD;
+  vector_int6_lit_phdr PT_LOAD;
+  vector_int7_text_phdr PT_LOAD;
+  vector_int7_lit_phdr PT_LOAD;
+  vector_kernel_text_phdr PT_LOAD;
+  vector_kernel_lit_phdr PT_LOAD;
+  vector_user_text_phdr PT_LOAD;
+  vector_user_lit_phdr PT_LOAD;
+  vector_double_text_phdr PT_LOAD;
+  vector_double_lit_phdr PT_LOAD;
+  reef_text_start_phdr PT_LOAD;
+  reef_data_ro_phdr PT_LOAD;
+  reef_data_phdr PT_LOAD;
+  reef_data_bss_phdr PT_LOAD;
+  system_heap_phdr PT_LOAD;
+  runtime_heap_phdr PT_LOAD;
+  buffer_heap_phdr PT_LOAD;
+  reef_stack_phdr PT_LOAD;
+}
+
+/*  Default entry point:  */
+ENTRY(_ResetVector)
+_rom_store_table = 0;
+
+/* ABI0 does not use Window base */
+PROVIDE(_memmap_vecbase_reset = XCHAL_VECBASE_RESET_PADDR);
+
+/* Various memory-map dependent cache attribute settings: */
+_memmap_cacheattr_wb_base = 0x44024000;
+_memmap_cacheattr_wt_base = 0x11021000;
+_memmap_cacheattr_bp_base = 0x22022000;
+_memmap_cacheattr_unused_mask = 0x00F00FFF;
+_memmap_cacheattr_wb_trapnull = 0x4422422F;
+_memmap_cacheattr_wba_trapnull = 0x4422422F;
+_memmap_cacheattr_wbna_trapnull = 0x25222222;
+_memmap_cacheattr_wt_trapnull = 0x1122122F;
+_memmap_cacheattr_bp_trapnull = 0x2222222F;
+_memmap_cacheattr_wb_strict = 0x44F24FFF;
+_memmap_cacheattr_wt_strict = 0x11F21FFF;
+_memmap_cacheattr_bp_strict = 0x22F22FFF;
+_memmap_cacheattr_wb_allvalid = 0x44224222;
+_memmap_cacheattr_wt_allvalid = 0x11221222;
+_memmap_cacheattr_bp_allvalid = 0x22222222;
+PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull);
+
+SECTIONS
+{
+  .ResetVector.text : ALIGN(4)
+  {
+    _ResetVector_text_start = ABSOLUTE(.);
+    KEEP (*(.ResetVector.text))
+    _ResetVector_text_end = ABSOLUTE(.);
+  } >vector_reset_text :vector_reset_text_phdr
+
+  .ResetVector.literal : ALIGN(4)
+  {
+    _ResetVector_literal_start = ABSOLUTE(.);
+    *(.ResetVector.literal)
+    _ResetVector_literal_end = ABSOLUTE(.);
+  } >vector_reset_lit :vector_reset_lit_phdr
+
+  .WindowVectors.text : ALIGN(4)
+  {
+    _WindowVectors_text_start = ABSOLUTE(.);
+    KEEP (*(.WindowVectors.text))
+    _WindowVectors_text_end = ABSOLUTE(.);
+  } >vector_base_text :vector_base_text_phdr
+
+  .Level2InterruptVector.literal : ALIGN(4)
+  {
+    _Level2InterruptVector_literal_start = ABSOLUTE(.);
+    *(.Level2InterruptVector.literal)
+    _Level2InterruptVector_literal_end = ABSOLUTE(.);
+  } >vector_int2_lit :vector_int2_lit_phdr
+
+  .Level2InterruptVector.text : ALIGN(4)
+  {
+    _Level2InterruptVector_text_start = ABSOLUTE(.);
+    KEEP (*(.Level2InterruptVector.text))
+    _Level2InterruptVector_text_end = ABSOLUTE(.);
+  } >vector_int2_text :vector_int2_text_phdr
+
+  .Level3InterruptVector.literal : ALIGN(4)
+  {
+    _Level3InterruptVector_literal_start = ABSOLUTE(.);
+    *(.Level3InterruptVector.literal)
+    _Level3InterruptVector_literal_end = ABSOLUTE(.);
+  } >vector_int3_lit :vector_int3_lit_phdr
+
+  .Level3InterruptVector.text : ALIGN(4)
+  {
+    _Level3InterruptVector_text_start = ABSOLUTE(.);
+    KEEP (*(.Level3InterruptVector.text))
+    _Level3InterruptVector_text_end = ABSOLUTE(.);
+  } >vector_int3_text :vector_int3_text_phdr
+
+  .Level4InterruptVector.literal : ALIGN(4)
+  {
+    _Level4InterruptVector_literal_start = ABSOLUTE(.);
+    *(.Level4InterruptVector.literal)
+    _Level4InterruptVector_literal_end = ABSOLUTE(.);
+  } >vector_int4_lit :vector_int4_lit_phdr
+
+  .Level4InterruptVector.text : ALIGN(4)
+  {
+    _Level4InterruptVector_text_start = ABSOLUTE(.);
+    KEEP (*(.Level4InterruptVector.text))
+    _Level4InterruptVector_text_end = ABSOLUTE(.);
+  } >vector_int4_text :vector_int4_text_phdr
+
+  .Level5InterruptVector.literal : ALIGN(4)
+  {
+    _Level5InterruptVector_literal_start = ABSOLUTE(.);
+    *(.Level5InterruptVector.literal)
+    _Level5InterruptVector_literal_end = ABSOLUTE(.);
+  } >vector_int5_lit :vector_int5_lit_phdr
+
+  .Level5InterruptVector.text : ALIGN(4)
+  {
+    _Level5InterruptVector_text_start = ABSOLUTE(.);
+    KEEP (*(.Level5InterruptVector.text))
+    _Level5InterruptVector_text_end = ABSOLUTE(.);
+  } >vector_int5_text :vector_int5_text_phdr
+
+  .DebugExceptionVector.literal : ALIGN(4)
+  {
+    _DebugExceptionVector_literal_start = ABSOLUTE(.);
+    *(.DebugExceptionVector.literal)
+    _DebugExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_int6_lit :vector_int6_lit_phdr
+
+  .DebugExceptionVector.text : ALIGN(4)
+  {
+    _DebugExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.DebugExceptionVector.text))
+    _DebugExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_int6_text :vector_int6_text_phdr
+
+  .NMIExceptionVector.literal : ALIGN(4)
+  {
+    _NMIExceptionVector_literal_start = ABSOLUTE(.);
+    *(.NMIExceptionVector.literal)
+    _NMIExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_int7_lit :vector_int7_lit_phdr
+
+  .NMIExceptionVector.text : ALIGN(4)
+  {
+    _NMIExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.NMIExceptionVector.text))
+    _NMIExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_int7_text :vector_int7_text_phdr
+
+  .KernelExceptionVector.literal : ALIGN(4)
+  {
+    _KernelExceptionVector_literal_start = ABSOLUTE(.);
+    *(.KernelExceptionVector.literal)
+    _KernelExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_kernel_lit :vector_kernel_lit_phdr
+
+  .KernelExceptionVector.text : ALIGN(4)
+  {
+    _KernelExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.KernelExceptionVector.text))
+    _KernelExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_kernel_text :vector_kernel_text_phdr
+
+  .UserExceptionVector.literal : ALIGN(4)
+  {
+    _UserExceptionVector_literal_start = ABSOLUTE(.);
+    *(.UserExceptionVector.literal)
+    _UserExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_user_lit :vector_user_lit_phdr
+
+  .UserExceptionVector.text : ALIGN(4)
+  {
+    _UserExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.UserExceptionVector.text))
+    _UserExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_user_text :vector_user_text_phdr
+
+  .DoubleExceptionVector.literal : ALIGN(4)
+  {
+    _DoubleExceptionVector_literal_start = ABSOLUTE(.);
+    *(.DoubleExceptionVector.literal)
+    _DoubleExceptionVector_literal_end = ABSOLUTE(.);
+  } >vector_double_lit :vector_double_lit_phdr
+
+  .DoubleExceptionVector.text : ALIGN(4)
+  {
+    _DoubleExceptionVector_text_start = ABSOLUTE(.);
+    KEEP (*(.DoubleExceptionVector.text))
+    _DoubleExceptionVector_text_end = ABSOLUTE(.);
+  } >vector_double_text :vector_double_text_phdr
+
+  .text : ALIGN(4)
+  {
+    _stext = .;
+    _text_start = ABSOLUTE(.);
+    *(.entry.text)
+    *(.init.literal)
+    KEEP(*(.init))
+    *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
+    *(.fini.literal)
+    KEEP(*(.fini))
+    *(.gnu.version)
+    _text_end = ABSOLUTE(.);
+    _etext = .;
+  } >reef_text_start :reef_text_start_phdr
+
+  .reset.rodata : ALIGN(4)
+  {
+    _reset_rodata_start = ABSOLUTE(.);
+    *(.reset.rodata)
+    _reset_rodata_end = ABSOLUTE(.);
+  } >reef_data_ro :reef_data_ro_phdr
+
+  .rodata : ALIGN(4)
+  {
+    _rodata_start = ABSOLUTE(.);
+    *(.rodata)
+    *(.rodata.*)
+    *(.gnu.linkonce.r.*)
+    *(.rodata1)
+    __XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
+    KEEP (*(.xt_except_table))
+    KEEP (*(.gcc_except_table))
+    *(.gnu.linkonce.e.*)
+    *(.gnu.version_r)
+    KEEP (*(.eh_frame))
+    /*  C++ constructor and destructor tables, properly ordered:  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+    /*  C++ exception handlers table:  */
+    __XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
+    *(.xt_except_desc)
+    *(.gnu.linkonce.h.*)
+    __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
+    *(.xt_except_desc_end)
+    *(.dynamic)
+    *(.gnu.version_d)
+    . = ALIGN(4);		/* this table MUST be 4-byte aligned */
+    _bss_table_start = ABSOLUTE(.);
+    LONG(_bss_start)
+    LONG(_bss_end)
+    _bss_table_end = ABSOLUTE(.);
+    _rodata_end = ABSOLUTE(.);
+  } >reef_data :reef_data_phdr
+
+  .data : ALIGN(4)
+  {
+    _data_start = ABSOLUTE(.);
+    *(.data)
+    *(.data.*)
+    *(.gnu.linkonce.d.*)
+    KEEP(*(.gnu.linkonce.d.*personality*))
+    *(.data1)
+    *(.sdata)
+    *(.sdata.*)
+    *(.gnu.linkonce.s.*)
+    *(.sdata2)
+    *(.sdata2.*)
+    *(.gnu.linkonce.s2.*)
+    KEEP(*(.jcr))
+    _data_end = ABSOLUTE(.);
+  } >reef_data :reef_data_phdr
+
+  .lit4 : ALIGN(4)
+  {
+    _lit4_start = ABSOLUTE(.);
+    *(*.lit4)
+    *(.lit4.*)
+    *(.gnu.linkonce.lit4.*)
+    _lit4_end = ABSOLUTE(.);
+  } >reef_data :reef_data_phdr
+
+  .bss (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (8);
+    _bss_start = ABSOLUTE(.);
+    *(.dynsbss)
+    *(.sbss)
+    *(.sbss.*)
+    *(.gnu.linkonce.sb.*)
+    *(.scommon)
+    *(.sbss2)
+    *(.sbss2.*)
+    *(.gnu.linkonce.sb2.*)
+    *(.dynbss)
+    *(.bss)
+    *(.bss.*)
+    *(.gnu.linkonce.b.*)
+    *(COMMON)
+    . = ALIGN (8);
+    _bss_end = ABSOLUTE(.);
+  } >reef_data :reef_data_bss_phdr
+
+  /* stack */
+  _end = REEF_STACK_END;
+  PROVIDE(end = REEF_STACK_END);
+  _stack_sentry = REEF_STACK_END;
+  __stack = REEF_STACK_BASE;
+
+  .debug  0 :  { *(.debug) }
+  .line  0 :  { *(.line) }
+  .debug_srcinfo  0 :  { *(.debug_srcinfo) }
+  .debug_sfnames  0 :  { *(.debug_sfnames) }
+  .debug_aranges  0 :  { *(.debug_aranges) }
+  .debug_pubnames  0 :  { *(.debug_pubnames) }
+  .debug_info  0 :  { *(.debug_info) }
+  .debug_abbrev  0 :  { *(.debug_abbrev) }
+  .debug_line  0 :  { *(.debug_line) }
+  .debug_frame  0 :  { *(.debug_frame) }
+  .debug_str  0 :  { *(.debug_str) }
+  .debug_loc  0 :  { *(.debug_loc) }
+  .debug_macinfo  0 :  { *(.debug_macinfo) }
+  .debug_weaknames  0 :  { *(.debug_weaknames) }
+  .debug_funcnames  0 :  { *(.debug_funcnames) }
+  .debug_typenames  0 :  { *(.debug_typenames) }
+  .debug_varnames  0 :  { *(.debug_varnames) }
+
+  .xt.insn 0 :
+  {
+    KEEP (*(.xt.insn))
+    KEEP (*(.gnu.linkonce.x.*))
+  }
+  .xt.prop 0 :
+  {
+    KEEP (*(.xt.prop))
+    KEEP (*(.xt.prop.*))
+    KEEP (*(.gnu.linkonce.prop.*))
+  }
+  .xt.lit 0 :
+  {
+    KEEP (*(.xt.lit))
+    KEEP (*(.xt.lit.*))
+    KEEP (*(.gnu.linkonce.p.*))
+  }
+  .xt.profile_range 0 :
+  {
+    KEEP (*(.xt.profile_range))
+    KEEP (*(.gnu.linkonce.profile_range.*))
+  }
+  .xt.profile_ranges 0 :
+  {
+    KEEP (*(.xt.profile_ranges))
+    KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
+  }
+  .xt.profile_files 0 :
+  {
+    KEEP (*(.xt.profile_files))
+    KEEP (*(.gnu.linkonce.xt.profile_files.*))
+  }
+
+  .system_heap (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (32);
+    _system_heap_start = ABSOLUTE(.);
+    . = . + HEAP_SYSTEM_SIZE;
+    _system_heap_end = ABSOLUTE(.);
+  } >system_heap :system_heap_phdr
+
+  .runtime_heap (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (32);
+    _runtime_heap_start = ABSOLUTE(.);
+    . = . + HEAP_RUNTIME_SIZE;
+    _runtime_heap_end = ABSOLUTE(.);
+  } >runtime_heap :runtime_heap_phdr
+
+  .buffer_heap (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (32);
+    _system_heap_start = ABSOLUTE(.);
+    . = . + HEAP_BUFFER_SIZE;
+    _system_heap_end = ABSOLUTE(.);
+  } >buffer_heap :buffer_heap_phdr
+
+  .reef_stack (NOLOAD) : ALIGN(8)
+  {
+    . = ALIGN (4096);
+    _reef_stack_start = ABSOLUTE(.);
+    . = . + REEF_STACK_SIZE;
+    _reef_stack_end = ABSOLUTE(.);
+  } >reef_stack :reef_stack_phdr
+}
+
diff --git a/src/platform/haswell/platform.c b/src/platform/haswell/platform.c
new file mode 100644
index 0000000..89afb8e
--- /dev/null
+++ b/src/platform/haswell/platform.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <platform/memory.h>
+#include <platform/mailbox.h>
+#include <platform/shim.h>
+#include <platform/dma.h>
+#include <platform/clk.h>
+#include <platform/timer.h>
+#include <platform/pmc.h>
+#include <uapi/ipc.h>
+#include <reef/mailbox.h>
+#include <reef/dai.h>
+#include <reef/dma.h>
+#include <reef/interrupt.h>
+#include <reef/reef.h>
+#include <reef/work.h>
+#include <reef/clock.h>
+#include <reef/ipc.h>
+#include <reef/trace.h>
+#include <reef/agent.h>
+#include <reef/io.h>
+#include <reef/dma-trace.h>
+#include <reef/audio/component.h>
+#include <config.h>
+#include <string.h>
+#include <version.h>
+
+static const struct sof_ipc_fw_ready ready = {
+	.hdr = {
+		.cmd = SOF_IPC_FW_READY,
+		.size = sizeof(struct sof_ipc_fw_ready),
+	},
+	/* dspbox is for DSP initiated IPC, hostbox is for host initiated IPC */
+	.dspbox_offset = MAILBOX_HOST_OFFSET + MAILBOX_DSPBOX_OFFSET,
+	.hostbox_offset = MAILBOX_HOST_OFFSET + MAILBOX_HOSTBOX_OFFSET,
+	.dspbox_size = MAILBOX_DSPBOX_SIZE,
+	.hostbox_size = MAILBOX_HOSTBOX_SIZE,
+	.version = {
+		.build = REEF_BUILD,
+		.minor = REEF_MINOR,
+		.major = REEF_MAJOR,
+		.date = __DATE__,
+		.time = __TIME__,
+		.tag = REEF_TAG,
+	},
+	/* TODO: add capabilities */
+};
+
+static struct work_queue_timesource platform_generic_queue = {
+	.timer	 = {
+		.id = TIMER0,	/* external timer using SSP */
+		.irq = IRQ_NUM_TIMER1,
+	},
+	.clk		= CLK_CPU,
+	.notifier	= NOTIFIER_ID_CPU_FREQ,
+	.timer_set	= arch_timer_set,
+	.timer_clear	= arch_timer_clear,
+	.timer_get	= arch_timer_get_system,
+};
+
+struct timer *platform_timer = &platform_generic_queue.timer;
+
+int platform_boot_complete(uint32_t boot_message)
+{
+	uint64_t outbox = MAILBOX_HOST_OFFSET >> 3;
+
+	mailbox_dspbox_write(0, &ready, sizeof(ready));
+
+	/* now interrupt host to tell it we are done booting */
+	shim_write(SHIM_IPCD, outbox | SHIM_IPCD_BUSY);
+
+	/* boot now complete so we can relax the CPU */
+	clock_set_freq(CLK_CPU, CLK_DEFAULT_CPU_HZ);
+
+	return 0;
+}
+
+void platform_interrupt_set(int irq)
+{
+	arch_interrupt_set(irq);
+}
+
+/* clear mask in PISR, bits are W1C in docs but some bits need preserved ?? */
+void platform_interrupt_clear(uint32_t irq, uint32_t mask)
+{
+	switch (irq) {
+	case IRQ_NUM_EXT_DMAC0:
+	case IRQ_NUM_EXT_DMAC1:
+	case IRQ_NUM_EXT_SSP0:
+	case IRQ_NUM_EXT_SSP1:
+		interrupt_clear(irq);
+		break;
+	default:
+		break;
+	}
+}
+
+/* TODO: expand this to 64 bit - should we just return mask of IRQ numbers */
+uint32_t platform_interrupt_get_enabled(void)
+{
+	return shim_read(SHIM_IMRD);
+}
+
+void platform_interrupt_mask(uint32_t irq, uint32_t mask)
+{
+	switch (irq) {
+	case IRQ_NUM_EXT_SSP0:
+		shim_write(SHIM_IMRD, SHIM_IMRD_SSP0);
+		break;
+	case IRQ_NUM_EXT_SSP1:
+		shim_write(SHIM_IMRD, SHIM_IMRD_SSP1);
+		break;
+	case IRQ_NUM_EXT_DMAC0:
+		shim_write(SHIM_IMRD, SHIM_IMRD_DMAC0);
+		break;
+	case IRQ_NUM_EXT_DMAC1:
+		shim_write(SHIM_IMRD, SHIM_IMRD_DMAC1);
+		break;
+	default:
+		break;
+	}
+}
+
+void platform_interrupt_unmask(uint32_t irq, uint32_t mask)
+{
+	switch (irq) {
+	case IRQ_NUM_EXT_SSP0:
+		shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_SSP0);
+		break;
+	case IRQ_NUM_EXT_SSP1:
+		shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_SSP1);
+		break;
+	case IRQ_NUM_EXT_DMAC0:
+		shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_DMAC0);
+		break;
+	case IRQ_NUM_EXT_DMAC1:
+		shim_write(SHIM_IMRD, shim_read(SHIM_IMRD) & ~SHIM_IMRD_DMAC1);
+		break;
+	default:
+		break;
+	}
+}
+
+int platform_init(struct reef *reef)
+{
+	struct dma *dmac0;
+	struct dma *dmac1;
+	struct dai *ssp0;
+	struct dai *ssp1;
+
+	trace_point(TRACE_BOOT_PLATFORM_MBOX);
+
+	/* clear mailbox for early trace and debug */
+	bzero((void*)MAILBOX_BASE, IPC_MAX_MAILBOX_BYTES);
+
+	trace_point(TRACE_BOOT_PLATFORM_SHIM);
+
+	/* init work queues and clocks */
+	trace_point(TRACE_BOOT_SYS_WORK);
+	init_system_workq(&platform_generic_queue);
+
+	trace_point(TRACE_BOOT_PLATFORM_TIMER);
+	platform_timer_start(platform_timer);
+
+	trace_point(TRACE_BOOT_PLATFORM_CLOCK);
+	init_platform_clocks();
+
+	/* init the system agent */
+	sa_init(reef);
+
+	/* Set CPU to default frequency for booting */
+	trace_point(TRACE_BOOT_SYS_CPU_FREQ);
+	clock_set_freq(CLK_CPU, CLK_MAX_CPU_HZ);
+
+	/* set SSP clock to 25M */
+	trace_point(TRACE_BOOT_PLATFORM_SSP_FREQ);
+	clock_set_freq(CLK_SSP, 25000000);
+
+	/* initialise the host IPC mechanisms */
+	trace_point(TRACE_BOOT_PLATFORM_IPC);
+	ipc_init(reef);
+
+	dma_trace_init_early(&reef->ipc->dmat);
+
+	/* init DMACs */
+	trace_point(TRACE_BOOT_PLATFORM_DMA);
+	dmac0 = dma_get(DMA_ID_DMAC0);
+	if (dmac0 == NULL)
+		return -ENODEV;
+	dma_probe(dmac0);
+
+	/* clear the masks for dsp of the dmac*/
+	io_reg_update_bits(SHIM_BASE + SHIM_IMRD,
+			SHIM_IMRD_DMAC0, 0);
+
+	dmac1 = dma_get(DMA_ID_DMAC1);
+	if (dmac1 == NULL)
+		return -ENODEV;
+	dma_probe(dmac1);
+
+	/* clear the masks for dsp of the dmac*/
+	io_reg_update_bits(SHIM_BASE + SHIM_IMRD,
+			SHIM_IMRD_DMAC1, 0);
+
+	/* init SSP ports */
+	trace_point(TRACE_BOOT_PLATFORM_SSP);
+	ssp0 = dai_get(SOF_DAI_INTEL_SSP, 0);
+	if (ssp0 == NULL)
+		return -ENODEV;
+	dai_probe(ssp0);
+
+	ssp1 = dai_get(SOF_DAI_INTEL_SSP, 1);
+	if (ssp1 == NULL)
+		return -ENODEV;
+	dai_probe(ssp1);
+
+	/* Initialize DMA for Trace*/
+	dma_trace_init_complete(&reef->ipc->dmat);
+
+	return 0;
+}
diff --git a/src/platform/haswell/timer.c b/src/platform/haswell/timer.c
new file mode 100644
index 0000000..bb74330
--- /dev/null
+++ b/src/platform/haswell/timer.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of the Intel Corporation nor the
+ *     names of its contributors may be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ */
+
+#include <platform/timer.h>
+#include <platform/shim.h>
+#include <platform/interrupt.h>
+#include <reef/debug.h>
+#include <reef/audio/component.h>
+#include <stdint.h>
+
+void platform_timer_start(struct timer *timer)
+{
+}
+
+void platform_timer_stop(struct timer *timer)
+{
+}
+
+int platform_timer_set(struct timer *timer, uint64_t ticks)
+{
+	return 0;
+}
+
+void platform_timer_clear(struct timer *timer)
+{
+}
+
+uint64_t platform_timer_get(struct timer *timer)
+{
+	return 0;
+}
+
+/* get timestamp for host stream DMA position */
+void platform_host_timestamp(struct comp_dev *host,
+	struct sof_ipc_stream_posn *posn)
+{
+	int err;
+
+	/* get host postion */
+	err = comp_position(host, posn);
+	if (err == 0)
+		posn->flags |= SOF_TIME_HOST_VALID | SOF_TIME_HOST_64;
+}
+
+/* get timestamp for DAI stream DMA position */
+void platform_dai_timestamp(struct comp_dev *dai,
+	struct sof_ipc_stream_posn *posn)
+{
+	int err;
+
+	/* get DAI postion */
+	err = comp_position(dai, posn);
+	if (err == 0)
+		posn->flags |= SOF_TIME_DAI_VALID;
+
+	/* get SSP wallclock - DAI sets this to stream start value */
+	posn->wallclock = timer_get_system(platform_timer) - posn->wallclock;
+	posn->flags |= SOF_TIME_WALL_VALID | SOF_TIME_WALL_64;
+}
+
+/* get current wallclock for componnent */
+void platform_dai_wallclock(struct comp_dev *dai, uint64_t *wallclock)
+{
+	/* only 1 wallclock on HSW */
+	*wallclock = timer_get_system(platform_timer);
+}
+
+int timer_register(struct timer *timer, void(*handler)(void *arg), void *arg)
+{
+	switch (timer->id) {
+	case TIMER0:
+	case TIMER1:
+	case TIMER2:
+		return arch_timer_register(timer, handler, arg);
+	default:
+		return -EINVAL;
+	}
+}
-- 
2.14.1



More information about the Sound-open-firmware mailing list