mboxd: Make window size and number optional command line parameters

The window size and number command line parameters are used to control
the number of windows and the size of each of the windows in the window
cache which the reserved memory region is divided between.

Most people won't care about tuning these or just won't know what they
refer to. Additionally in the event we change how the window cache
works or allow a non-constant window size then the meaning of these
becomes unclear.

Daemon implementations may also choose to just not implement a cache so
making these required parameters may hurt portability.

Make the window size and number command line parameters optional rather
than required so that they can be largly ignored while people who really
care about tuning them can still do so.

The default for now is to have windows of size 1MB and to map the entire
reserved memory region. That is:
number of windows = size of memory region / size of windows

This means that the size of the reserved memory region can be reduced
and the daemon will adapt to this.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Change-Id: I7c7bbef6e5d31d1372ec3a755877cacc6c135cce
diff --git a/mboxd.c b/mboxd.c
index 6f060d8..0ebba56 100644
--- a/mboxd.c
+++ b/mboxd.c
@@ -53,13 +53,15 @@
 
 #define USAGE \
 "\nUsage: %s [-V | --version] [-h | --help] [-v[v] | --verbose] [-s | --syslog]\n" \
-"\t\t-n | --window-num <num>\n" \
-"\t\t-w | --window-size <size>M\n" \
+"\t\t[-n | --window-num <num>]\n" \
+"\t\t[-w | --window-size <size>M]\n" \
 "\t\t-f | --flash <size>[K|M]\n\n" \
 "\t-v | --verbose\t\tBe [more] verbose\n" \
 "\t-s | --syslog\t\tLog output to syslog (pointless without -v)\n" \
 "\t-n | --window-num\tThe number of windows\n" \
+"\t\t\t\t(default: fill the reserved memory region)\n" \
 "\t-w | --window-size\tThe window size (power of 2) in MB\n" \
+"\t\t\t\t(default: 1MB)\n" \
 "\t-f | --flash\t\tSize of flash in [K|M] bytes\n\n"
 
 static int poll_loop(struct mbox_context *context)
@@ -179,7 +181,7 @@
 			  struct mbox_context *context)
 {
 	char *endptr;
-	int opt, i;
+	int opt;
 
 	static const struct option long_options[] = {
 		{ "flash",		required_argument,	0, 'f' },
@@ -195,9 +197,6 @@
 	verbosity = MBOX_LOG_NONE;
 	mbox_vlog = &mbox_log_console;
 
-	/* Default to 1 window of size flash_size */
-	context->windows.default_size = context->flash_size;
-	context->windows.num = 1;
 	context->current = NULL; /* No current window */
 
 	while ((opt = getopt_long(argc, argv, "f:w::n::vsVh", long_options, NULL))
@@ -269,34 +268,7 @@
 		return false;
 	}
 
-	if (!context->windows.num) {
-		fprintf(stderr, "Must specify a non-zero number of windows\n"
-				"If unsure - select 4 (-n 4)\n");
-		return false;
-	}
-
-	if (!context->windows.default_size) {
-		fprintf(stderr, "Must specify a non-zero window size\n"
-				"If unsure - select 1M (-w 1)\n");
-		return false;
-	}
-
 	MSG_OUT("Flash size: 0x%.8x\n", context->flash_size);
-	MSG_OUT("Number of Windows: %d\n", context->windows.num);
-	MSG_OUT("Window size: 0x%.8x\n", context->windows.default_size);
-
-	context->windows.window = calloc(context->windows.num,
-					 sizeof(*context->windows.window));
-	if (!context->windows.window) {
-		MSG_ERR("Memory allocation failed\n");
-		free(context);
-		exit(1);
-	}
-
-	for (i = 0; i < context->windows.num; i++) {
-		init_window_state(&context->windows.window[i],
-				  context->windows.default_size);
-	}
 
 	if (verbosity) {
 		MSG_OUT("%s logging\n", verbosity == MBOX_LOG_DEBUG ? "Debug" :
@@ -347,7 +319,7 @@
 	}
 
 	/* We've found the reserved memory region -> we can assign to windows */
-	rc = init_window_mem(context);
+	rc = init_windows(context);
 	if (rc) {
 		goto finish;
 	}
@@ -386,8 +358,7 @@
 	free_flash_dev(context);
 	free_lpc_dev(context);
 	free_mbox_dev(context);
-	free_window_dirty_bytemap(context);
-	free(context->windows.window);
+	free_windows(context);
 	free(context);
 
 	return rc;
diff --git a/mboxd_windows.c b/mboxd_windows.c
index fd46770..c64d19b 100644
--- a/mboxd_windows.c
+++ b/mboxd_windows.c
@@ -54,7 +54,7 @@
  * @window:	The window to initialise
  * @size:	The size of the window
  */
-void init_window_state(struct window_context *window, uint32_t size)
+static void init_window_state(struct window_context *window, uint32_t size)
 {
 	window->mem = NULL;
 	window->flash_offset = FLASH_OFFSET_UNINIT;
@@ -69,7 +69,7 @@
  *
  * Return:	0 on success otherwise negative error code
  */
-int init_window_mem(struct mbox_context *context)
+static int init_window_mem(struct mbox_context *context)
 {
 	void *mem_location = context->mem;
 	int i;
@@ -95,6 +95,60 @@
 
 	return 0;
 }
+/*
+ * init_windows() - Initalise the window cache
+ * @context:    The mbox context pointer
+ *
+ * Return:      0 on success otherwise negative
+ */
+int init_windows(struct mbox_context *context)
+{
+	int i;
+
+	/* Check if window size and number set - otherwise set to default */
+	if (!context->windows.default_size) {
+		/* Default to 1MB windows */
+		context->windows.default_size = 1 << 20;
+	}
+	MSG_OUT("Window size: 0x%.8x\n", context->windows.default_size);
+	if (!context->windows.num) {
+		/* Use the entire reserved memory region by default */
+		context->windows.num = context->mem_size /
+				       context->windows.default_size;
+	}
+	MSG_OUT("Number of Windows: %d\n", context->windows.num);
+
+	context->windows.window = calloc(context->windows.num,
+					 sizeof(*context->windows.window));
+	if (!context->windows.window) {
+		MSG_ERR("Memory allocation failed\n");
+		return -1;
+	}
+
+	for (i = 0; i < context->windows.num; i++) {
+		init_window_state(&context->windows.window[i],
+				  context->windows.default_size);
+	}
+
+	return init_window_mem(context);
+}
+
+/*
+ * free_windows() - Free the window cache
+ * @context:	The mbox context pointer
+ */
+void free_windows(struct mbox_context *context)
+{
+	int i;
+
+	/* Check window cache has actually been allocated */
+	if (context->windows.window) {
+		for (i = 0; i < context->windows.num; i++) {
+			free(context->windows.window[i].dirty_bmap);
+		}
+		free(context->windows.window);
+	}
+}
 
 /* Write from Window Functions */
 
@@ -310,19 +364,6 @@
 }
 
 /*
- * free_window_dirty_bytemap() - free all window dirty bytemaps
- * @context:	The mbox context pointer
- */
-void free_window_dirty_bytemap(struct mbox_context *context)
-{
-	int i;
-
-	for (i = 0; i < context->windows.num; i++) {
-		free(context->windows.window[i].dirty_bmap);
-	}
-}
-
-/*
  * set_window_bytemap() - Set the window bytemap
  * @context:	The mbox context pointer
  * @cur:	The window to set the bytemap of
diff --git a/mboxd_windows.h b/mboxd_windows.h
index 90e1d46..b81007d 100644
--- a/mboxd_windows.h
+++ b/mboxd_windows.h
@@ -22,8 +22,8 @@
 #define WITH_FLUSH	true
 
 /* Initialisation Functions */
-void init_window_state(struct window_context *window, uint32_t size);
-int init_window_mem(struct mbox_context *context);
+int init_windows(struct mbox_context *context);
+void free_windows(struct mbox_context *context);
 /* Write From Window Functions */
 int write_from_window_v1(struct mbox_context *context,
 			 uint32_t offset_bytes, uint32_t count_bytes);
@@ -31,7 +31,6 @@
 		      uint32_t count, uint8_t type);
 /* Window Management Functions */
 void alloc_window_dirty_bytemap(struct mbox_context *context);
-void free_window_dirty_bytemap(struct mbox_context *context);
 int set_window_bytemap(struct mbox_context *context, struct window_context *cur,
 		       uint32_t offset, uint32_t size, uint8_t val);
 void close_current_window(struct mbox_context *context, bool set_bmc_event,