diff --git a/tools/buildman/README b/tools/buildman/README
index aaf0a10f8f7cf5861a491f7869efdfa77493981e..d4e840480a0922964e1fa90b0069bff984362ef0 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -108,6 +108,15 @@ behaviour is a superset of exact or substring matching. Examples are:
 * '^tegra[23]0$' All boards with either Tegra20 or Tegra30 SoC
 * 'powerpc'      All PowerPC boards
 
+While the default is to OR the terms together, you can also make use of
+the '&' operator to limit the selection:
+
+* 'freescale & arm sandbox'  All Freescale boards with ARM architecture,
+                             plus sandbox
+
+It is convenient to use the -n option to see whaat will be built based on
+the subset given.
+
 Buildman does not store intermediate object files. It optionally copies
 the binary output into a directory when a build is successful. Size
 information is always recorded. It needs a fair bit of disk space to work,
diff --git a/tools/buildman/board.py b/tools/buildman/board.py
index 7bcc93262eba16cd0b4a0cb6eeb5371e2957e4f6..a3332876240ea673e02c51db3d0bcab0e181e387 100644
--- a/tools/buildman/board.py
+++ b/tools/buildman/board.py
@@ -5,6 +5,72 @@
 
 import re
 
+class Expr:
+    """A single regular expression for matching boards to build"""
+
+    def __init__(self, expr):
+        """Set up a new Expr object.
+
+        Args:
+            expr: String cotaining regular expression to store
+        """
+        self._expr = expr
+        self._re = re.compile(expr)
+
+    def Matches(self, props):
+        """Check if any of the properties match the regular expression.
+
+        Args:
+           props: List of properties to check
+        Returns:
+           True if any of the properties match the regular expression
+        """
+        for prop in props:
+            if self._re.match(prop):
+                return True
+        return False
+
+    def __str__(self):
+        return self._expr
+
+class Term:
+    """A list of expressions each of which must match with properties.
+
+    This provides a list of 'AND' expressions, meaning that each must
+    match the board properties for that board to be built.
+    """
+    def __init__(self):
+        self._expr_list = []
+        self._board_count = 0
+
+    def AddExpr(self, expr):
+        """Add an Expr object to the list to check.
+
+        Args:
+            expr: New Expr object to add to the list of those that must
+                  match for a board to be built.
+        """
+        self._expr_list.append(Expr(expr))
+
+    def __str__(self):
+        """Return some sort of useful string describing the term"""
+        return '&'.join([str(expr) for expr in self._expr_list])
+
+    def Matches(self, props):
+        """Check if any of the properties match this term
+
+        Each of the expressions in the term is checked. All must match.
+
+        Args:
+           props: List of properties to check
+        Returns:
+           True if all of the expressions in the Term match, else False
+        """
+        for expr in self._expr_list:
+            if not expr.Matches(props):
+                return False
+        return True
+
 class Board:
     """A particular board that we can build"""
     def __init__(self, status, arch, cpu, soc, vendor, board_name, target, options):
@@ -124,6 +190,55 @@ class Boards:
         """
         return [board.target for board in self._boards if board.build_it]
 
+    def _BuildTerms(self, args):
+        """Convert command line arguments to a list of terms.
+
+        This deals with parsing of the arguments. It handles the '&'
+        operator, which joins several expressions into a single Term.
+
+        For example:
+            ['arm & freescale sandbox', 'tegra']
+
+        will produce 3 Terms containing expressions as follows:
+            arm, freescale
+            sandbox
+            tegra
+
+        The first Term has two expressions, both of which must match for
+        a board to be selected.
+
+        Args:
+            args: List of command line arguments
+        Returns:
+            A list of Term objects
+        """
+        syms = []
+        for arg in args:
+            for word in arg.split():
+                sym_build = []
+                for term in word.split('&'):
+                    if term:
+                        sym_build.append(term)
+                    sym_build.append('&')
+                syms += sym_build[:-1]
+        terms = []
+        term = None
+        oper = None
+        for sym in syms:
+            if sym == '&':
+                oper = sym
+            elif oper:
+                term.AddExpr(sym)
+                oper = None
+            else:
+                if term:
+                    terms.append(term)
+                term = Term()
+                term.AddExpr(sym)
+        if term:
+            terms.append(term)
+        return terms
+
     def SelectBoards(self, args):
         """Mark boards selected based on args
 
@@ -137,26 +252,21 @@ class Boards:
             due to each argument, arranged by argument.
         """
         result = {}
-        argres = {}
-        for arg in args:
-            result[arg] = 0
-            argres[arg] = re.compile(arg)
+        terms = self._BuildTerms(args)
+
         result['all'] = 0
+        for term in terms:
+            result[str(term)] = 0
 
         for board in self._boards:
-            if args:
-                for arg in args:
-                    argre = argres[arg]
-                    match = False
-                    for prop in board.props:
-                        match = argre.match(prop)
-                        if match:
-                            break
-                    if match:
-                        if not board.build_it:
-                            board.build_it = True
-                            result[arg] += 1
-                            result['all'] += 1
+            if terms:
+                match = False
+                for term in terms:
+                    if term.Matches(board.props):
+                        board.build_it = True
+                        result[str(term)] += 1
+                        result['all'] += 1
+                        break
             else:
                 board.build_it = True
                 result['all'] += 1
diff --git a/tools/buildman/test.py b/tools/buildman/test.py
index 502c9b4e80bd57ff22228a1bc230b2ae8fca10b3..a51c9429e91280d11d8e1cf01add3c3f64b6dcea 100644
--- a/tools/buildman/test.py
+++ b/tools/buildman/test.py
@@ -165,5 +165,53 @@ class TestBuild(unittest.TestCase):
         args = ['tegra20']
         control.DoBuildman(options, args)
 
+    def testBoardSingle(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards(['sandbox']),
+                         {'all': 1, 'sandbox': 1})
+
+    def testBoardArch(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards(['arm']),
+                         {'all': 2, 'arm': 2})
+
+    def testBoardArchSingle(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards(['arm sandbox']),
+                         {'all': 3, 'arm': 2, 'sandbox' : 1})
+
+    def testBoardArchSingleMultiWord(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards(['arm', 'sandbox']),
+                         {'all': 3, 'arm': 2, 'sandbox' : 1})
+
+    def testBoardSingleAnd(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards(['Tester & arm']),
+                         {'all': 2, 'Tester&arm': 2})
+
+    def testBoardTwoAnd(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards(['Tester', '&', 'arm',
+                                                   'Tester' '&', 'powerpc',
+                                                   'sandbox']),
+                         {'all': 5, 'Tester&powerpc': 2, 'Tester&arm': 2,
+                          'sandbox' : 1})
+
+    def testBoardAll(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards([]), {'all': 5})
+
+    def testBoardRegularExpression(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards(['T.*r&^Po']),
+                         {'T.*r&^Po': 2, 'all': 2})
+
+    def testBoardDuplicate(self):
+        """Test single board selection"""
+        self.assertEqual(self.boards.SelectBoards(['sandbox sandbox',
+                                                   'sandbox']),
+                         {'all': 1, 'sandbox': 1})
+
 if __name__ == "__main__":
     unittest.main()