From ff37970f80bf9f8b3cb11fe17ed78b84bcd8c737 Mon Sep 17 00:00:00 2001
From: Jeremy Ranger <jranger@es.net>
Date: Sat, 20 Jan 2024 08:30:59 -0500
Subject: [PATCH] regmap: Break up automatic import chain to avoid pulling on
 too much

This change reduces what is imported via the top-level __init__.py file to stop
importing the world. Instead, users should simply import the sub-packages they
need explicitly.
---
 .gitignore                               |  1 +
 src/regio/regmap/__init__.py             |  4 ----
 src/regio/regmap/io/ffi.py               |  5 +++--
 src/regio/regmap/io/mmap.py              |  5 +++--
 src/regio/regmap/spec/__init__.py        | 11 ++++++++++-
 src/regio/regmap/types/__init__.py       |  2 --
 src/regio/tools/templates/block_py.j2    |  2 +-
 src/regio/tools/templates/toplevel_py.j2 |  8 ++++++--
 8 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/.gitignore b/.gitignore
index 5169ef4..f207ee4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ dist/
 poetry.lock
 setup.py
 __pycache__
+regio-*.bar*.bin
diff --git a/src/regio/regmap/__init__.py b/src/regio/regmap/__init__.py
index cdc6a69..e69de29 100644
--- a/src/regio/regmap/__init__.py
+++ b/src/regio/regmap/__init__.py
@@ -1,4 +0,0 @@
-#---------------------------------------------------------------------------------------------------
-from .io import *
-from .proxy import *
-from .spec import *
diff --git a/src/regio/regmap/io/ffi.py b/src/regio/regmap/io/ffi.py
index d518cb9..99d81e6 100644
--- a/src/regio/regmap/io/ffi.py
+++ b/src/regio/regmap/io/ffi.py
@@ -1,7 +1,7 @@
 #---------------------------------------------------------------------------------------------------
 __all__ = ()
 
-import ctypes as _ctypes, ctypes.util as _cutil
+import ctypes as _ctypes
 import os
 
 #---------------------------------------------------------------------------------------------------
@@ -59,6 +59,8 @@ def update(self, ctype, addr, clr_mask, set_mask):
 #---------------------------------------------------------------------------------------------------
 class LibC:
     def __init__(self):
+        import ctypes.util as _cutil
+
         # Get the C library's path.
         # https://docs.python.org/3/library/ctypes.html#finding-shared-libraries
         self.path = _cutil.find_library('c')
@@ -124,4 +126,3 @@ def munmap(self, addr, length):
 #---------------------------------------------------------------------------------------------------
 # Instantiate on import of the module.
 ctype = CType()
-libc = LibC()
diff --git a/src/regio/regmap/io/mmap.py b/src/regio/regmap/io/mmap.py
index 21d1706..32d9e9a 100644
--- a/src/regio/regmap/io/mmap.py
+++ b/src/regio/regmap/io/mmap.py
@@ -64,6 +64,7 @@ def __init__(self, path, data_width,
         self.page_no = (offset + mmap.PAGESIZE - 1) // mmap.PAGESIZE
         self.page_offset = offset % mmap.PAGESIZE
         self.mmap_size = mmap_size - self.page_no * mmap.PAGESIZE
+        self.libc = ffi.LibC()
 
         # Get the C type for accessing a single data word.
         self.endian = endian.get()
@@ -88,7 +89,7 @@ def start(self):
 
         # Map the file's memory region into the virtual address space.
         with self.path.open('r+b') as fo:
-            self._addr_p = ffi.libc.mmap(
+            self._addr_p = self.libc.mmap(
                 ffi.ctype.pointer.NULL, self.mmap_size, mmap.PROT_READ | mmap.PROT_WRITE,
                 mmap.MAP_SHARED, fo.fileno(), self.page_no * mmap.PAGESIZE)
 
@@ -101,7 +102,7 @@ def stop(self):
             return
 
         # Unmap the memory region from the virtual address space.
-        ffi.libc.munmap(self._addr_p, self.mmap_size)
+        self.libc.munmap(self._addr_p, self.mmap_size)
         del self._addr_p
         del self._base_addr
         super().stop()
diff --git a/src/regio/regmap/spec/__init__.py b/src/regio/regmap/spec/__init__.py
index acac488..6113cd5 100644
--- a/src/regio/regmap/spec/__init__.py
+++ b/src/regio/regmap/spec/__init__.py
@@ -1,8 +1,17 @@
 #---------------------------------------------------------------------------------------------------
+__all__ = (
+    'AddressSpace',
+    'Array',
+    'Access',
+    'Field',
+    'Register',
+    'Structure',
+    'Union',
+)
+
 from .address import AddressSpace
 from .array import Array
 from .field import Access, Field
-from .info import *
 from .register import Register
 from .structure import Structure
 from .union import Union
diff --git a/src/regio/regmap/types/__init__.py b/src/regio/regmap/types/__init__.py
index 9ff22d2..e69de29 100644
--- a/src/regio/regmap/types/__init__.py
+++ b/src/regio/regmap/types/__init__.py
@@ -1,2 +0,0 @@
-#---------------------------------------------------------------------------------------------------
-__all__ = ()
diff --git a/src/regio/tools/templates/block_py.j2 b/src/regio/tools/templates/block_py.j2
index e61441b..9cf00ff 100644
--- a/src/regio/tools/templates/block_py.j2
+++ b/src/regio/tools/templates/block_py.j2
@@ -10,7 +10,7 @@ __all__ = (
     '{{ blk.name_lower }}_block',
 )
 
-from regio.regmap import *
+from regio.regmap.spec import *
 
 #---------------------------------------------------------------------------------------------------
 {%- set data_width = 32 %}{#- TODO: Shouldn't be hardcoded. Get from YAML? #}
diff --git a/src/regio/tools/templates/toplevel_py.j2 b/src/regio/tools/templates/toplevel_py.j2
index 2939430..b75183c 100644
--- a/src/regio/tools/templates/toplevel_py.j2
+++ b/src/regio/tools/templates/toplevel_py.j2
@@ -10,8 +10,7 @@
 #---------------------------------------------------------------------------------------------------
 __all__ = ()
 
-import pathlib
-from regio.regmap import *
+from regio.regmap.spec import AddressSpace
 {% for blk in blks.keys() | sort: %}
 from .blocks.{{ blk }}_block import *
 {%- endfor %}
@@ -61,6 +60,11 @@ __all__ += (
 )
 {% endfor %}
 #---------------------------------------------------------------------------------------------------
+import pathlib
+
+from regio.regmap.io import DevMmapIOForSpec
+from regio.regmap.proxy import for_io_by_path
+
 PCI_DEVICES_DIR = pathlib.Path('/sys/bus/pci/devices')
 
 def _hex_to_int(path):