Index: kernel/generic/include/mm/frame.h
===================================================================
--- kernel/generic/include/mm/frame.h	(revision ce940da51be45d72ee3e62d4d5593519b5991e7c)
+++ kernel/generic/include/mm/frame.h	(revision 3a4ac81ba8f6e2a39733e3ea182453fee6ed9b92)
@@ -159,4 +159,5 @@
 
 extern void frame_init(void);
+extern bool frame_adjust_zone_bounds(bool, uintptr_t *, size_t *);
 extern void *frame_alloc_generic(uint8_t, frame_flags_t, size_t *);
 extern void *frame_alloc(uint8_t, frame_flags_t);
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision ce940da51be45d72ee3e62d4d5593519b5991e7c)
+++ kernel/generic/src/mm/frame.c	(revision 3a4ac81ba8f6e2a39733e3ea182453fee6ed9b92)
@@ -1264,4 +1264,36 @@
 }
 
+/** Adjust bounds of physical memory region according to low/high memory split.
+ *
+ * @param low[in]	If true, the adujstment is performed to make the region
+ *			fit in the low memory. Otherwise the adjustment is
+ *			performed to make the region fit in the high memory.
+ * @param basep[inout]	Pointer to a variable which contains the region's base
+ *			address and which may receive the adjusted base address.
+ * @param sizep[inout]	Pointer to a variable which contains the region's size
+ *			and which may receive the adjusted size.
+ * @retun		True if the region still exists even after the
+ *			adjustment, false otherwise.
+ */
+bool frame_adjust_zone_bounds(bool low, uintptr_t *basep, size_t *sizep)
+{
+	uintptr_t limit = config.identity_size;
+
+	if (low) {
+		if (*basep > limit)
+			return false;
+		if (*basep + *sizep > limit)
+			*sizep = limit - *basep;
+	} else {
+		if (*basep + *sizep <= limit)
+			return false;
+		if (*basep <= limit) {
+			*sizep -= limit - *basep;
+			*basep = limit;
+		}
+	}
+	return true;
+}
+
 /** Return total size of all zones.
  *
