Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ HelenOS.config	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -615,2 +615,10 @@
 @ "efi" GRUB for UEFI
 ! [PLATFORM=ia32|PLATFORM=amd64] GRUB_ARCH (choice)
+
+% uImage OS type
+@ "2" NetBSD stage 2 boot loader
+! [PLATFORM=arm32&MACHINE=beagleboardxm] UIMAGE_OS (choice)
+
+% uImage OS type
+@ "5" Linux kernel
+! [PLATFORM=arm32&MACHINE!=beagleboardxm] UIMAGE_OS (choice)
Index: boot/Makefile.uboot
===================================================================
--- boot/Makefile.uboot	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ boot/Makefile.uboot	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -40,5 +40,5 @@
 
 $(POST_OUTPUT): $(BIN_OUTPUT)
-	$(MKUIMAGE) -name "$(IMAGE_NAME)" -laddr $(LADDR) -saddr $(SADDR) $< $@
+	$(MKUIMAGE) -name "$(IMAGE_NAME)" -laddr $(LADDR) -saddr $(SADDR) -ostype $(UIMAGE_OS) $< $@
 
 clean:
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ boot/arch/arm32/Makefile.inc	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -49,5 +49,5 @@
 BITS = 32
 ENDIANESS = LE
-EXTRA_CFLAGS = -march=$(subst _,-,$(PROCESSOR))
+EXTRA_CFLAGS = -march=$(subst _,-,$(PROCESSOR)) -mno-unaligned-access
 
 ifeq ($(MACHINE), gta02)
Index: defaults/arm32/gta02/Makefile.config
===================================================================
--- defaults/arm32/gta02/Makefile.config	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ defaults/arm32/gta02/Makefile.config	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -3,3 +3,3 @@
 
 # RAM disk format
-RDFMT = tmpfs
+RDFMT = fat
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ kernel/arch/arm32/Makefile.inc	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -33,5 +33,5 @@
 ATSIGN = %
 
-GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR))
+GCC_CFLAGS += -fno-omit-frame-pointer -mapcs-frame -march=$(subst _,-,$(PROCESSOR)) -mno-unaligned-access
 
 BITS = 32
Index: kernel/arch/arm32/include/asm.h
===================================================================
--- kernel/arch/arm32/include/asm.h	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ kernel/arch/arm32/include/asm.h	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -46,4 +46,6 @@
  *
  * ARMv7 introduced wait for event and wait for interrupt (wfe/wfi).
+ * ARM920T has custom coprocessor action to do the same. See ARM920T Technical
+ * Reference Manual ch 4.9 p. 4-23 (103 in the PDF)
  */
 NO_TRACE static inline void cpu_sleep(void)
@@ -51,4 +53,6 @@
 #ifdef PROCESSOR_armv7_a
 	asm volatile ( "wfe" :: );
+#elif defined(MACHINE_gta02)
+	asm volatile ( "mcr p15,0,R0,c7,c0,4" :: );
 #endif
 }
Index: kernel/arch/arm32/include/barrier.h
===================================================================
--- kernel/arch/arm32/include/barrier.h	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ kernel/arch/arm32/include/barrier.h	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -47,6 +47,24 @@
 #define write_barrier()   asm volatile ("" ::: "memory")
 
-#define smc_coherence(a)
-#define smc_coherence_block(a, l)
+/*
+ * There are multiple ways ICache can be implemented on ARM machines. Namely
+ * PIPT, VIPT, and ASID and VMID tagged VIVT (see ARM Architecture Reference
+ * Manual B3.11.2 (p. 1383).  However, CortexA8 Manual states: "For maximum
+ * compatibility across processors, ARM recommends that operating systems target
+ * the ARMv7 base architecture that uses ASID-tagged VIVT instruction caches,
+ * and do not assume the presence of the IVIPT extension. Software that relies
+ * on the IVIPT extension might fail in an unpredictable way on an ARMv7
+ * implementation that does not include the IVIPT extension." (7.2.6 p. 245).
+ * Only PIPT invalidates cache for all VA aliases if one block is invalidated.
+ *
+ * @note: Supporting ASID and VMID tagged VIVT may need to add ICache
+ * maintenance to other places than just smc.
+ */
+
+/* Available on both all supported arms,
+ * invalidates entire ICache so the written value does not matter. */
+#define smc_coherence(a) asm volatile ( "mcr p15, 0, r0, c7, c5, 0")
+#define smc_coherence_block(a, l) smc_coherence(a)
+
 
 #endif
Index: kernel/arch/arm32/include/regutils.h
===================================================================
--- kernel/arch/arm32/include/regutils.h	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ kernel/arch/arm32/include/regutils.h	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -41,20 +41,27 @@
 #define STATUS_REG_MODE_MASK         0x1f
 
-#define CP15_R1_MMU_ENABLE_BIT       (1 << 0)
-#define CP15_R1_ALIGNMENT_ENABLE_BIT (1 << 1)
-#define CP15_R1_CACHE_ENABLE_BIT     (1 << 2)
-#define CP15_R1_BRANCH_PREDICT_BIT   (1 << 11)
-#define CP15_R1_INST_CACHE_BIT       (1 << 12)
-#define CP15_R1_HIGH_VECTORS_BIT     (1 << 13)
-#define CP15_R1_ROUND_ROBIN_BIT      (1 << 14)
-#define CP15_R1_HA_ENABLE_BIT        (1 << 17)
-#define CP15_R1_WXN_BIT              (1 << 19) /* Only if virt. supported */
-#define CP15_R1_UWXN_BIT             (1 << 20) /* Only if virt. supported */
-#define CP15_R1_FI_BIT               (1 << 21)
-#define CP15_R1_VE_BIT               (1 << 24)
-#define CP15_R1_EE_BIT               (1 << 25)
-#define CP15_R1_NMFI_BIT             (1 << 27)
-#define CP15_R1_TRE_BIT              (1 << 28)
-#define CP15_R1_AFE_BIT              (1 << 29)
+/* COntrol register bit values see ch. B4.1.130 of ARM Architecture Reference
+ * Manual ARMv7-A and ARMv7-R edition, page 1687 */
+#define CP15_R1_MMU_EN            (1 << 0)
+#define CP15_R1_ALIGN_CHECK_EN    (1 << 1)  /* Allow alignemnt check */
+#define CP15_R1_CACHE_EN          (1 << 2)
+#define CP15_R1_CP15_BARRIER_EN   (1 << 5)
+#define CP15_R1_B_EN              (1 << 7)  /* ARMv6- only big endian switch */
+#define CP15_R1_SWAP_EN           (1 << 10)
+#define CP15_R1_BRANCH_PREDICT_EN (1 << 11)
+#define CP15_R1_INST_CACHE_EN     (1 << 12)
+#define CP15_R1_HIGH_VECTORS_EN   (1 << 13)
+#define CP15_R1_ROUND_ROBIN_EN    (1 << 14)
+#define CP15_R1_HW_ACCESS_FLAG_EN (1 << 17)
+#define CP15_R1_WRITE_XN_EN       (1 << 19) /* Only if virt. supported */
+#define CP15_R1_USPCE_WRITE_XN_EN (1 << 20) /* Only if virt. supported */
+#define CP15_R1_FAST_IRQ_EN       (1 << 21) /* Disbale impl.specific features */
+#define CP15_R1_UNALIGNED_EN      (1 << 22) /* Must be 1 on armv7 */
+#define CP15_R1_IRQ_VECTORS_EN    (1 << 24)
+#define CP15_R1_BIG_ENDIAN_EXC    (1 << 25)
+#define CP15_R1_NMFI_EN           (1 << 27)
+#define CP15_R1_TEX_REMAP_EN      (1 << 28)
+#define CP15_R1_ACCESS_FLAG_EN    (1 << 29)
+#define CP15_R1_THUMB_EXC_EN      (1 << 30)
 
 /* ARM Processor Operation Modes */
Index: kernel/arch/arm32/src/cpu/cpu.c
===================================================================
--- kernel/arch/arm32/src/cpu/cpu.c	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ kernel/arch/arm32/src/cpu/cpu.c	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -97,8 +97,8 @@
 }
 
-/** Does nothing on ARM. */
+/** Enables unaligned access and caching for armv6+ */
 void cpu_arch_init(void)
 {
-#if defined(PROCESSOR_armv7_a)
+#if defined(PROCESSOR_armv7_a) | defined(PROCESSOR_armv6)
 	uint32_t control_reg = 0;
 	asm volatile (
@@ -107,10 +107,27 @@
 	);
 	
-	/* Turn off tex remap */
-	control_reg &= ~CP15_R1_TRE_BIT;
-	/* Turn off accessed flag */
-	control_reg &= ~(CP15_R1_AFE_BIT | CP15_R1_HA_ENABLE_BIT);
-	/* Enable caching */
-	control_reg |= CP15_R1_CACHE_ENABLE_BIT;
+	/* Turn off tex remap, RAZ ignores writes prior to armv7 */
+	control_reg &= ~CP15_R1_TEX_REMAP_EN;
+	/* Turn off accessed flag, RAZ ignores writes prior to armv7 */
+	control_reg &= ~(CP15_R1_ACCESS_FLAG_EN | CP15_R1_HW_ACCESS_FLAG_EN);
+	/* Enable unaligned access, RAZ ignores writes prior to armv6
+	 * switchable on armv6, RAO ignores writes on armv7,
+	 * see ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition
+	 * L.3.1 (p. 2456) */
+	control_reg |= CP15_R1_UNALIGNED_EN;
+	/* Disable alignment checks, this turns unaligned access to undefined,
+	 * unless U bit is set. */
+	control_reg &= ~CP15_R1_ALIGN_CHECK_EN;
+	/* Enable caching, On arm prior to armv7 there is only one level
+	 * of caches. Data cache is coherent.
+	 * "This means that the behavior of accesses from the same observer to
+	 * different VAs, that are translated to the same PA
+	 * with the same memory attributes, is fully coherent."
+	 *    ARM Architecture Reference Manual ARMv7-A and ARMv7-R Edition
+	 *    B3.11.1 (p. 1383)
+	 * ICache coherency is elaborate on in barrier.h.
+	 * We are safe to turn these on.
+	 */
+	control_reg |= CP15_R1_CACHE_EN | CP15_R1_INST_CACHE_EN;
 	
 	asm volatile (
@@ -122,5 +139,5 @@
 
 /** Retrieves processor identification and stores it to #CPU.arch */
-void cpu_identify(void) 
+void cpu_identify(void)
 {
 	arch_cpu_identify(&CPU->arch);
Index: kernel/arch/arm32/src/exception.c
===================================================================
--- kernel/arch/arm32/src/exception.c	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ kernel/arch/arm32/src/exception.c	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -143,5 +143,5 @@
 	
 	/* switch on the high vectors bit */
-	control_reg |= CP15_R1_HIGH_VECTORS_BIT;
+	control_reg |= CP15_R1_HIGH_VECTORS_EN;
 	
 	asm volatile (
Index: kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c
===================================================================
--- kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -96,8 +96,10 @@
 		++order;
 	}
-	printf("Allocating %d (2^%d) frames.\n", size, order);
 	/* prefer highmem as we don't care about virtual mapping. */
 	void *buffer = frame_alloc(order, FRAME_LOWMEM);
-	ASSERT(buffer);
+	if (!buffer) {
+		printf("Failed to allocate framebuffer.\n");
+		return;
+	}
 
 	amdm37x_dispc_setup_fb(beagleboard.dispc, width, height, bpp,
Index: kernel/arch/arm32/src/mm/page_fault.c
===================================================================
--- kernel/arch/arm32/src/mm/page_fault.c	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ kernel/arch/arm32/src/mm/page_fault.c	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -41,4 +41,90 @@
 #include <interrupt.h>
 #include <print.h>
+
+
+/**
+ * FSR encoding ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition.
+ *
+ * B3.13.3 page B3-1406 (PDF page 1406)
+ */
+typedef enum {
+	DFSR_SOURCE_ALIGN = 0x0001,
+	DFSR_SOURCE_CACHE_MAINTENANCE = 0x0004,
+	DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1 = 0x000c,
+	DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2 = 0x000e,
+	DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1 = 0x040c,
+	DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2 = 0x040e,
+	DFSR_SOURCE_TRANSLATION_L1 = 0x0005,
+	DFSR_SOURCE_TRANSLATION_L2 = 0x0007,
+	DFSR_SOURCE_ACCESS_FLAG_L1 = 0x0003,  /**< @note: This used to be alignment enc. */
+	DFSR_SOURCE_ACCESS_FLAG_L2 = 0x0006,
+	DFSR_SOURCE_DOMAIN_L1 = 0x0009,
+	DFSR_SOURCE_DOMAIN_L2 = 0x000b,
+	DFSR_SOURCE_PERMISSION_L1 = 0x000d,
+	DFSR_SOURCE_PERMISSION_L2 = 0x000f,
+	DFSR_SOURCE_DEBUG = 0x0002,
+	DFSR_SOURCE_SYNC_EXTERNAL = 0x0008,
+	DFSR_SOURCE_TLB_CONFLICT = 0x0400,
+	DFSR_SOURCE_LOCKDOWN = 0x0404, /**< @note: Implementation defined */
+	DFSR_SOURCE_COPROCESSOR = 0x040a, /**< @note Implementation defined */
+	DFSR_SOURCE_SYNC_PARITY = 0x0409,
+	DFSR_SOURCE_ASYNC_EXTERNAL = 0x0406,
+	DFSR_SOURCE_ASYNC_PARITY = 0x0408,
+	DFSR_SOURCE_MASK = 0x0000040f,
+} dfsr_source_t;
+
+static inline const char * dfsr_source_to_str(dfsr_source_t source)
+{
+	switch (source)	{
+	case DFSR_SOURCE_TRANSLATION_L1:
+		return "Translation fault L1";
+	case DFSR_SOURCE_TRANSLATION_L2:
+		return "Translation fault L2";
+	case DFSR_SOURCE_PERMISSION_L1:
+		return "Permission fault L1";
+	case DFSR_SOURCE_PERMISSION_L2:
+		return "Permission fault L2";
+	case DFSR_SOURCE_ALIGN:
+		return "Alignment fault";
+	case DFSR_SOURCE_CACHE_MAINTENANCE:
+		return "Instruction cache maintenance fault";
+	case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1:
+		return "Synchronous external abort on translation table walk level 1";
+	case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2:
+		return "Synchronous external abort on translation table walk level 2";
+	case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1:
+		return "Synchronous parity error on translation table walk level 1";
+	case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2:
+		return "Synchronous parity error on translation table walk level 2";
+	case DFSR_SOURCE_ACCESS_FLAG_L1:
+		return "Access flag fault L1";
+	case DFSR_SOURCE_ACCESS_FLAG_L2:
+		return "Access flag fault L2";
+	case DFSR_SOURCE_DOMAIN_L1:
+		return "Domain fault L1";
+	case DFSR_SOURCE_DOMAIN_L2:
+		return "Domain flault L2";
+	case DFSR_SOURCE_DEBUG:
+		return "Debug event";
+	case DFSR_SOURCE_SYNC_EXTERNAL:
+		return "Synchronous external abort";
+	case DFSR_SOURCE_TLB_CONFLICT:
+		return "TLB conflict abort";
+	case DFSR_SOURCE_LOCKDOWN:
+		return "Lockdown (Implementation defined)";
+	case DFSR_SOURCE_COPROCESSOR:
+		return "Coprocessor abort (Implementation defined)";
+	case DFSR_SOURCE_SYNC_PARITY:
+		return "Synchronous parity error on memory access";
+	case DFSR_SOURCE_ASYNC_EXTERNAL:
+		return "Asynchronous external abort";
+	case DFSR_SOURCE_ASYNC_PARITY:
+		return "Asynchronous parity error on memory access";
+	case DFSR_SOURCE_MASK:
+		break;
+	}
+	return "Unknown data abort";
+}
+
 
 /** Returns value stored in comnbined/data fault status register.
@@ -158,8 +244,42 @@
 void data_abort(unsigned int exc_no, istate_t *istate)
 {
-	uintptr_t badvaddr = read_data_fault_address_register();
+	const uintptr_t badvaddr = read_data_fault_address_register();
+	const fault_status_t fsr = read_data_fault_status_register();
+	const dfsr_source_t source = fsr.raw & DFSR_SOURCE_MASK;
+
+	switch (source)	{
+	case DFSR_SOURCE_TRANSLATION_L1:
+	case DFSR_SOURCE_TRANSLATION_L2:
+	case DFSR_SOURCE_PERMISSION_L1:
+	case DFSR_SOURCE_PERMISSION_L2:
+		/* Page fault is handled further down */
+		break;
+	case DFSR_SOURCE_ALIGN:
+	case DFSR_SOURCE_CACHE_MAINTENANCE:
+	case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L1:
+	case DFSR_SOURCE_SYNC_EXTERNAL_TRANSLATION_L2:
+	case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L1:
+	case DFSR_SOURCE_SYNC_PARITY_TRANSLATION_L2:
+	case DFSR_SOURCE_ACCESS_FLAG_L1:
+	case DFSR_SOURCE_ACCESS_FLAG_L2:
+	case DFSR_SOURCE_DOMAIN_L1:
+	case DFSR_SOURCE_DOMAIN_L2:
+	case DFSR_SOURCE_DEBUG:
+	case DFSR_SOURCE_SYNC_EXTERNAL:
+	case DFSR_SOURCE_TLB_CONFLICT:
+	case DFSR_SOURCE_LOCKDOWN:
+	case DFSR_SOURCE_COPROCESSOR:
+	case DFSR_SOURCE_SYNC_PARITY:
+	case DFSR_SOURCE_ASYNC_EXTERNAL:
+	case DFSR_SOURCE_ASYNC_PARITY:
+	case DFSR_SOURCE_MASK:
+		/* Weird abort stuff */
+		fault_if_from_uspace(istate, "Unhandled abort %s at address: "
+		    "%#x.", dfsr_source_to_str(source), badvaddr);
+		panic("Unhandled abort %s at address: %#x.",
+		    dfsr_source_to_str(source), badvaddr);
+	}
 
 #if defined(PROCESSOR_armv6) | defined(PROCESSOR_armv7_a)
-	fault_status_t fsr = read_data_fault_status_register();
 	const pf_access_t access =
 	    fsr.data.wr ? PF_ACCESS_WRITE : PF_ACCESS_READ;
@@ -169,5 +289,5 @@
 #error "Unsupported architecture"
 #endif
-	int ret = as_page_fault(badvaddr, access, istate);
+	const int ret = as_page_fault(badvaddr, access, istate);
 
 	if (ret == AS_PF_FAULT) {
Index: tools/mkuimage.py
===================================================================
--- tools/mkuimage.py	(revision 47d2ca977dd4d30de1bd6680037e3db92762dbb8)
+++ tools/mkuimage.py	(revision d085df109266ca3c7cd68ff490a353f281809857)
@@ -60,4 +60,5 @@
 	load_addr = 0
 	start_addr = 0
+	os_type = 5 #Linux is the default
 
 	while len(args) >= 2 and args[0][0] == '-':
@@ -71,4 +72,6 @@
 		elif opt == 'saddr':
 			start_addr = (int)(optarg, 0)
+		elif opt == 'ostype':
+			os_type = (int)(optarg, 0)
 		else:
 			print(base_name + ": Unrecognized option.")
@@ -85,10 +88,10 @@
 
 	try:
-		mkuimage(inf_name, outf_name, image_name, load_addr, start_addr)
+		mkuimage(inf_name, outf_name, image_name, load_addr, start_addr, os_type)
 	except:
 		os.remove(outf_name)
 		raise
 
-def mkuimage(inf_name, outf_name, image_name, load_addr, start_addr):
+def mkuimage(inf_name, outf_name, image_name, load_addr, start_addr, os_type):
 	inf = open(inf_name, 'rb')
 	outf = open(outf_name, 'wb')
@@ -120,5 +123,5 @@
 	header.start_addr = start_addr	# Address of entry point
 	header.data_crc = data_crc
-	header.os = 2			# NetBSD
+	header.os = os_type
 	header.arch = 2			# ARM
 	header.img_type = 2		# Kernel
