kernel: introduce supervisor-only stacks

These stacks are appropriate for threads that run purely in
supervisor mode, and also as stacks for interrupt and exception
handling.

Two new arch defines are introduced:

- ARCH_KERNEL_STACK_GUARD_SIZE
- ARCH_KERNEL_STACK_OBJ_ALIGN

New public declaration macros:

- K_KERNEL_STACK_RESERVED
- K_KERNEL_STACK_EXTERN
- K_KERNEL_STACK_DEFINE
- K_KERNEL_STACK_ARRAY_DEFINE
- K_KERNEL_STACK_MEMBER
- K_KERNEL_STACK_SIZEOF

If user mode is not enabled, K_KERNEL_STACK_* and K_THREAD_STACK_*
are equivalent.

Separately generated privilege elevation stacks are now declared
like kernel stacks, removing the need for K_PRIVILEGE_STACK_ALIGN.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
diff --git a/scripts/gen_kobject_list.py b/scripts/gen_kobject_list.py
index b932581..167755b 100755
--- a/scripts/gen_kobject_list.py
+++ b/scripts/gen_kobject_list.py
@@ -175,33 +175,13 @@
 
 class KobjectInstance:
     def __init__(self, type_obj, addr):
-        global thread_counter
-        global sys_mutex_counter
-        global futex_counter
-        global stack_counter
-
         self.addr = addr
         self.type_obj = type_obj
 
         # Type name determined later since drivers needs to look at the
         # API struct address
         self.type_name = None
-
-        if self.type_obj.name == "k_thread":
-            # Assign an ID for this thread object, used to track its
-            # permissions to other kernel objects
-            self.data = thread_counter
-            thread_counter = thread_counter + 1
-        elif self.type_obj.name == "sys_mutex":
-            self.data = "&kernel_mutexes[%d]" % sys_mutex_counter
-            sys_mutex_counter += 1
-        elif self.type_obj.name == "k_futex":
-            self.data = "&futex_data[%d]" % futex_counter
-            futex_counter += 1
-        elif self.type_obj.name == STACK_TYPE:
-            stack_counter += 1
-        else:
-            self.data = 0
+        self.data = 0
 
 
 class KobjectType:
@@ -512,11 +492,18 @@
 
 
 def find_kobjects(elf, syms):
+    global thread_counter
+    global sys_mutex_counter
+    global futex_counter
+    global stack_counter
+
     if not elf.has_dwarf_info():
         sys.exit("ELF file has no DWARF information")
 
     app_smem_start = syms["_app_smem_start"]
     app_smem_end = syms["_app_smem_end"]
+    user_stack_start = syms["z_user_stacks_start"]
+    user_stack_end = syms["z_user_stacks_end"]
 
     di = elf.get_dwarf_info()
 
@@ -630,6 +617,26 @@
                   % (ko.type_obj.name, hex(addr)))
             continue
 
+        if (ko.type_obj.name == STACK_TYPE and
+                (addr < user_stack_start or addr >= user_stack_end)):
+            debug("skip kernel-only stack at %s" % hex(addr))
+            continue
+
+        # At this point we know the object will be included in the gperf table
+        if ko.type_obj.name == "k_thread":
+            # Assign an ID for this thread object, used to track its
+            # permissions to other kernel objects
+            ko.data = thread_counter
+            thread_counter = thread_counter + 1
+        elif ko.type_obj.name == "sys_mutex":
+            ko.data = "&kernel_mutexes[%d]" % sys_mutex_counter
+            sys_mutex_counter += 1
+        elif ko.type_obj.name == "k_futex":
+            ko.data = "&futex_data[%d]" % futex_counter
+            futex_counter += 1
+        elif ko.type_obj.name == STACK_TYPE:
+            stack_counter += 1
+
         if ko.type_obj.name != "device":
             # Not a device struct so we immediately know its type
             ko.type_name = kobject_to_enum(ko.type_obj.name)
@@ -748,9 +755,11 @@
     if "CONFIG_GEN_PRIV_STACKS" in syms:
         metadata_names["K_OBJ_THREAD_STACK_ELEMENT"] = "stack_data"
         if stack_counter != 0:
+            # Same as K_KERNEL_STACK_ARRAY_DEFINE, but routed to a different
+            # memory section.
             fp.write("static uint8_t Z_GENERIC_SECTION(.priv_stacks.noinit) "
-                     " __aligned(Z_PRIVILEGE_STACK_ALIGN)"
-                     " priv_stacks[%d][CONFIG_PRIVILEGED_STACK_SIZE];\n"
+                     " __aligned(Z_KERNEL_STACK_OBJ_ALIGN)"
+                     " priv_stacks[%d][Z_KERNEL_STACK_LEN(CONFIG_PRIVILEGED_STACK_SIZE)];\n"
                      % stack_counter)
 
             fp.write("static struct z_stack_data stack_data[%d] = {\n"