Browse Source

Merge tag 'dm-pull-15jan19' of git://git.denx.de/u-boot-dm

Fix recent changes to serial API for driver model
Buildman clang support and a few fixes
Small fixes to 'dm tree' and regmap test
Improve sandbox build compatibility
A few other minor fixes
Tom Rini 5 years ago
parent
commit
aac0c29d4b

+ 3 - 10
.travis.yml

@@ -109,16 +109,9 @@ script:
  #
  # From buildman, exit code 129 means warnings only.  If we've been asked to
  # use clang only do one configuration.
- - if [[ "${TOOLCHAIN}" == "clang" ]]; then
+ - if [[ "${BUILDMAN}" != "" ]]; then
      ret=0;
-     make O=../.bm-work/${TEST_PY_BD} HOSTCC=clang-7 CC=clang-7 -j$(nproc)
-       KCFLAGS=-Werror sandbox_config all || ret=$?;
-     if [[ $ret -ne 0 ]]; then
-       exit $ret;
-     fi;
-   elif [[ "${BUILDMAN}" != "" ]]; then
-     ret=0;
-     tools/buildman/buildman -P -E ${BUILDMAN} || ret=$?;
+     tools/buildman/buildman -P -E ${BUILDMAN} ${OVERRIDE}|| ret=$?;
      if [[ $ret -ne 0 && $ret -ne 129 ]]; then
        tools/buildman/buildman -sdeP ${BUILDMAN};
        exit $ret;
@@ -351,7 +344,7 @@ matrix:
       env:
         - TEST_PY_BD="sandbox"
           BUILDMAN="^sandbox$"
-          TOOLCHAIN="clang"
+          OVERRIDE="clang-7"
     - name: "test/py sandbox_spl"
       env:
         - TEST_PY_BD="sandbox_spl"

+ 0 - 2
arch/sandbox/config.mk

@@ -11,11 +11,9 @@ PLATFORM_LIBS += -lrt
 ifneq ($(NO_SDL),)
 PLATFORM_CPPFLAGS += -DSANDBOX_NO_SDL
 else
-ifdef CONFIG_SANDBOX_SDL
 PLATFORM_LIBS += $(shell sdl-config --libs)
 PLATFORM_CPPFLAGS += $(shell sdl-config --cflags)
 endif
-endif
 
 cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
 	-Wl,--start-group $(u-boot-main) -Wl,--end-group \

+ 1 - 1
arch/sandbox/cpu/sdl.c

@@ -6,7 +6,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <linux/input.h>
-#include <SDL/SDL.h>
+#include <SDL.h>
 #include <asm/state.h>
 
 /**

+ 4 - 6
arch/sandbox/dts/sandbox.dts

@@ -100,11 +100,13 @@
 		eeprom@2c {
 			reg = <0x2c>;
 			compatible = "i2c-eeprom";
+			sandbox,emul = <&emul_eeprom>;
 		};
 
 		rtc_0: rtc@43 {
 			reg = <0x43>;
 			compatible = "sandbox-rtc";
+			sandbox,emul = <&emul0>;
 		};
 		sandbox_pmic: sandbox_pmic {
 			reg = <0x40>;
@@ -115,18 +117,14 @@
 		};
 
 		i2c_emul: emul {
-			#address-cells = <1>;
-			#size-cells = <0>;
 			reg = <0xff>;
 			compatible = "sandbox,i2c-emul-parent";
-			emul-eeprom {
-				reg = <0x2c>;
+			emul_eeprom: emul-eeprom {
 				compatible = "sandbox,i2c-eeprom";
 				sandbox,filename = "i2c.bin";
 				sandbox,size = <256>;
 			};
-			emul0 {
-				reg = <0x43>;
+			emul0: emul0 {
 				compatible = "sandbox,i2c-rtc";
 			};
 		};

+ 4 - 2
arch/sandbox/dts/sandbox64.dts

@@ -90,11 +90,13 @@
 		eeprom@2c {
 			reg = <0x2c>;
 			compatible = "i2c-eeprom";
+			sandbox,emul = <&emul_eeprom>;
 		};
 
 		rtc_0: rtc@43 {
 			reg = <0x43>;
 			compatible = "sandbox-rtc";
+			sandbox,emul = <&emul0>;
 		};
 		sandbox_pmic: sandbox_pmic {
 			reg = <0x40>;
@@ -107,12 +109,12 @@
 		i2c_emul: emul {
 			reg = <0xff>;
 			compatible = "sandbox,i2c-emul-parent";
-			emul-eeprom {
+			emul_eeprom: emul-eeprom {
 				compatible = "sandbox,i2c-eeprom";
 				sandbox,filename = "i2c.bin";
 				sandbox,size = <256>;
 			};
-			emul0 {
+			emul0: emul0 {
 				compatible = "sandbox,i2c-rtc";
 			};
 		};

+ 12 - 0
arch/sandbox/include/asm/io.h

@@ -173,6 +173,18 @@ static inline void _outsw(volatile u16 *port, const void *buf, int ns)
 {
 }
 
+static inline void memset_io(volatile void *addr, unsigned char val, int count)
+{
+}
+
+static inline void memcpy_fromio(void *dst, const volatile void *src, int count)
+{
+}
+
+static inline void memcpy_toio(volatile void *dst, const void *src, int count)
+{
+}
+
 #define insw(port, buf, ns)		_insw((u16 *)port, buf, ns)
 #define outsw(port, buf, ns)		_outsw((u16 *)port, buf, ns)
 

+ 8 - 4
arch/x86/lib/acpi_table.c

@@ -342,6 +342,7 @@ static void acpi_create_spcr(struct acpi_spcr *spcr)
 	struct acpi_table_header *header = &(spcr->header);
 	struct serial_device_info serial_info = {0};
 	ulong serial_address, serial_offset;
+	struct udevice *dev;
 	uint serial_config;
 	uint serial_width;
 	int access_size;
@@ -353,7 +354,10 @@ static void acpi_create_spcr(struct acpi_spcr *spcr)
 	header->length = sizeof(struct acpi_spcr);
 	header->revision = 2;
 
-	ret = serial_getinfo(&serial_info);
+	/* Read the device once, here. It is reused below */
+	ret = uclass_first_device_err(UCLASS_SERIAL, &dev);
+	if (!ret)
+		ret = serial_getinfo(dev, &serial_info);
 	if (ret)
 		serial_info.type = SERIAL_CHIP_UNKNOWN;
 
@@ -431,9 +435,9 @@ static void acpi_create_spcr(struct acpi_spcr *spcr)
 		break;
 	}
 
-	ret = serial_getconfig(&serial_config);
-	if (ret)
-		serial_config = SERIAL_DEFAULT_CONFIG;
+	serial_config = SERIAL_DEFAULT_CONFIG;
+	if (dev)
+		ret = serial_getconfig(dev, &serial_config);
 
 	spcr->parity = SERIAL_GET_PARITY(serial_config);
 	spcr->stop_bits = SERIAL_GET_STOP(serial_config);

+ 2 - 2
common/fdt_support.c

@@ -1025,7 +1025,7 @@ static u64 of_bus_default_map(fdt32_t *addr, const fdt32_t *range,
 	s  = fdt_read_number(range + na + pna, ns);
 	da = fdt_read_number(addr, na);
 
-	debug("OF: default map, cp=%llu, s=%llu, da=%llu\n", cp, s, da);
+	debug("OF: default map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
 
 	if (da < cp || da >= (cp + s))
 		return OF_BAD_ADDR;
@@ -1080,7 +1080,7 @@ static u64 of_bus_isa_map(fdt32_t *addr, const fdt32_t *range,
 	s  = fdt_read_number(range + na + pna, ns);
 	da = fdt_read_number(addr + 1, na - 1);
 
-	debug("OF: ISA map, cp=%llu, s=%llu, da=%llu\n", cp, s, da);
+	debug("OF: ISA map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
 
 	if (da < cp || da >= (cp + s))
 		return OF_BAD_ADDR;

+ 2 - 2
drivers/core/dump.c

@@ -16,7 +16,7 @@ static void show_devices(struct udevice *dev, int depth, int last_flag)
 	struct udevice *child;
 
 	/* print the first 20 characters to not break the tree-format. */
-	printf(" %-10.10s  %d  [ %c ]   %-20.20s  ", dev->uclass->uc_drv->name,
+	printf(" %-10.10s  %2d  [ %c ]   %-20.20s  ", dev->uclass->uc_drv->name,
 	       dev_get_uclass_index(dev, NULL),
 	       dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);
 
@@ -49,7 +49,7 @@ void dm_dump_all(void)
 
 	root = dm_root();
 	if (root) {
-		printf(" Class    index  Probed  Driver                Name\n");
+		printf(" Class     Index  Probed  Driver                Name\n");
 		printf("-----------------------------------------------------------\n");
 		show_devices(root, -1, 0);
 	}

+ 4 - 5
drivers/net/sandbox-raw.c

@@ -152,7 +152,6 @@ static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev)
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
 	const char *ifname;
-	u32 local;
 	int ret;
 
 	pdata->iobase = dev_read_addr(dev);
@@ -173,10 +172,10 @@ static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev)
 		       priv->host_ifindex, priv->host_ifname);
 	}
 
-	local = sandbox_eth_raw_os_is_local(priv->host_ifname);
-	if (local < 0)
-		return local;
-	priv->local = local;
+	ret = sandbox_eth_raw_os_is_local(priv->host_ifname);
+	if (ret < 0)
+		return ret;
+	priv->local = ret;
 
 	return 0;
 }

+ 9 - 18
drivers/serial/serial-uclass.c

@@ -294,49 +294,40 @@ void serial_setbrg(void)
 		ops->setbrg(gd->cur_serial_dev, gd->baudrate);
 }
 
-int serial_getconfig(uint *config)
+int serial_getconfig(struct udevice *dev, uint *config)
 {
 	struct dm_serial_ops *ops;
 
-	if (!gd->cur_serial_dev)
-		return 0;
-
-	ops = serial_get_ops(gd->cur_serial_dev);
+	ops = serial_get_ops(dev);
 	if (ops->getconfig)
-		return ops->getconfig(gd->cur_serial_dev, config);
+		return ops->getconfig(dev, config);
 
 	return 0;
 }
 
-int serial_setconfig(uint config)
+int serial_setconfig(struct udevice *dev, uint config)
 {
 	struct dm_serial_ops *ops;
 
-	if (!gd->cur_serial_dev)
-		return 0;
-
-	ops = serial_get_ops(gd->cur_serial_dev);
+	ops = serial_get_ops(dev);
 	if (ops->setconfig)
-		return ops->setconfig(gd->cur_serial_dev, config);
+		return ops->setconfig(dev, config);
 
 	return 0;
 }
 
-int serial_getinfo(struct serial_device_info *info)
+int serial_getinfo(struct udevice *dev, struct serial_device_info *info)
 {
 	struct dm_serial_ops *ops;
 
-	if (!gd->cur_serial_dev)
-		return -ENODEV;
-
 	if (!info)
 		return -EINVAL;
 
 	info->baudrate = gd->baudrate;
 
-	ops = serial_get_ops(gd->cur_serial_dev);
+	ops = serial_get_ops(dev);
 	if (ops->getinfo)
-		return ops->getinfo(gd->cur_serial_dev, info);
+		return ops->getinfo(dev, info);
 
 	return -EINVAL;
 }

+ 0 - 5
include/common.h

@@ -351,8 +351,6 @@ void smp_set_core_boot_addr(unsigned long addr, int corenr);
 void smp_kick_all_cpus(void);
 
 /* $(CPU)/serial.c */
-struct serial_device_info;
-
 int	serial_init   (void);
 void	serial_setbrg (void);
 void	serial_putc   (const char);
@@ -360,9 +358,6 @@ void	serial_putc_raw(const char);
 void	serial_puts   (const char *);
 int	serial_getc   (void);
 int	serial_tstc   (void);
-int	serial_getconfig(uint *config);
-int	serial_setconfig(uint config);
-int	serial_getinfo(struct serial_device_info *info);
 
 /* $(CPU)/speed.c */
 int	get_clocks (void);

+ 2 - 1
include/log.h

@@ -73,7 +73,8 @@ static inline int log_uc_cat(enum uclass_id id)
  * @return 0 if log record was emitted, -ve on error
  */
 int _log(enum log_category_t cat, enum log_level_t level, const char *file,
-	 int line, const char *func, const char *fmt, ...);
+	 int line, const char *func, const char *fmt, ...)
+		__attribute__ ((format (__printf__, 6, 7)));
 
 /* Define this at the top of a file to add a prefix to debug messages */
 #ifndef pr_fmt

+ 13 - 1
include/regmap.h

@@ -248,6 +248,8 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
  * @cond:	Break condition (usually involving @val)
  * @sleep_us:	Maximum time to sleep between reads in us (0 tight-loops).
  * @timeout_ms:	Timeout in ms, 0 means never timeout
+ * @test_add_time: Used for sandbox testing - amount of time to add after
+ *		starting the loop (0 if not testing)
  *
  * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read
  * error return value in case of a error read. In the two former cases,
@@ -256,8 +258,12 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
  *
  * This is modelled after the regmap_read_poll_timeout macros in linux but
  * with millisecond timeout.
+ *
+ * The _test version is for sandbox testing only. Do not use this in normal
+ * code as it advances the timer.
  */
-#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_ms) \
+#define regmap_read_poll_timeout_test(map, addr, val, cond, sleep_us, \
+				      timeout_ms, test_add_time) \
 ({ \
 	unsigned long __start = get_timer(0); \
 	int __ret; \
@@ -267,6 +273,8 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
 			break; \
 		if (cond) \
 			break; \
+		if (IS_ENABLED(CONFIG_SANDBOX) && test_add_time) \
+			sandbox_timer_add_offset(test_add_time); \
 		if ((timeout_ms) && get_timer(__start) > (timeout_ms)) { \
 			__ret = regmap_read((map), (addr), &(val)); \
 			break; \
@@ -277,6 +285,10 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
 	__ret ?: ((cond) ? 0 : -ETIMEDOUT); \
 })
 
+#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_ms) \
+	regmap_read_poll_timeout_test(map, addr, val, cond, sleep_us, \
+				      timeout_ms, 0) \
+
 /**
  * regmap_update_bits() - Perform a read/modify/write using a mask
  *

+ 35 - 3
include/serial.h

@@ -235,9 +235,7 @@ struct dm_serial_ops {
 	 * Get a current config for this device.
 	 *
 	 * @dev: Device pointer
-	 * @parity: parity to use
-	 * @bits: bits number to use
-	 * @stop: stop bits number to use
+	 * @serial_config: Returns config information (see SERIAL_... above)
 	 * @return 0 if OK, -ve on error
 	 */
 	int (*getconfig)(struct udevice *dev, uint *serial_config);
@@ -257,6 +255,7 @@ struct dm_serial_ops {
 	 *
 	 * @dev: Device pointer
 	 * @info: struct serial_device_info to fill
+	 * @return 0 if OK, -ve on error
 	 */
 	int (*getinfo)(struct udevice *dev, struct serial_device_info *info);
 };
@@ -281,6 +280,39 @@ struct serial_dev_priv {
 /* Access the serial operations for a device */
 #define serial_get_ops(dev)	((struct dm_serial_ops *)(dev)->driver->ops)
 
+/**
+ * serial_getconfig() - Get the uart configuration
+ * (parity, 5/6/7/8 bits word length, stop bits)
+ *
+ * Get a current config for this device.
+ *
+ * @dev: Device pointer
+ * @serial_config: Returns config information (see SERIAL_... above)
+ * @return 0 if OK, -ve on error
+ */
+int serial_getconfig(struct udevice *dev, uint *config);
+
+/**
+ * serial_setconfig() - Set up the uart configuration
+ * (parity, 5/6/7/8 bits word length, stop bits)
+ *
+ * Set up a new config for this device.
+ *
+ * @dev: Device pointer
+ * @serial_config: number of bits, parity and number of stopbits to use
+ * @return 0 if OK, -ve on error
+ */
+int serial_setconfig(struct udevice *dev, uint config);
+
+/**
+ * serial_getinfo() - Get serial device information
+ *
+ * @dev: Device pointer
+ * @info: struct serial_device_info to fill
+ * @return 0 if OK, -ve on error
+ */
+int serial_getinfo(struct udevice *dev, struct serial_device_info *info);
+
 void atmel_serial_initialize(void);
 void mcf_serial_initialize(void);
 void mpc85xx_serial_initialize(void);

+ 2 - 2
lib/efi_loader/efi_file.c

@@ -221,8 +221,8 @@ static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file,
 	struct file_handle *fh = to_fh(file);
 	efi_status_t ret;
 
-	EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle, file_name,
-		  open_mode, attributes);
+	EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle,
+		  (wchar_t *)file_name, open_mode, attributes);
 
 	/* Check parameters */
 	if (!file || !new_handle || !file_name) {

+ 0 - 10
lib/fdtdec.c

@@ -95,16 +95,6 @@ fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
 
 	debug("%s: %s: ", __func__, prop_name);
 
-	if (na > (sizeof(fdt_addr_t) / sizeof(fdt32_t))) {
-		debug("(na too large for fdt_addr_t type)\n");
-		return FDT_ADDR_T_NONE;
-	}
-
-	if (ns > (sizeof(fdt_size_t) / sizeof(fdt32_t))) {
-		debug("(ns too large for fdt_size_t type)\n");
-		return FDT_ADDR_T_NONE;
-	}
-
 	prop = fdt_getprop(blob, node, prop_name, &len);
 	if (!prop) {
 		debug("(not found)\n");

+ 4 - 3
test/dm/regmap.c

@@ -160,9 +160,10 @@ static int dm_test_regmap_poll(struct unit_test_state *uts)
 	start = get_timer(0);
 
 	ut_asserteq(-ETIMEDOUT,
-		    regmap_read_poll_timeout(map, 0, reg,
-					     (reg == 0xcacafafa),
-					     1, 5 * CONFIG_SYS_HZ));
+		    regmap_read_poll_timeout_test(map, 0, reg,
+						  (reg == 0xcacafafa),
+						  1, 5 * CONFIG_SYS_HZ,
+						  5 * CONFIG_SYS_HZ));
 
 	ut_assert(get_timer(start) > (5 * CONFIG_SYS_HZ));
 

+ 11 - 8
test/dm/serial.c

@@ -23,23 +23,24 @@ static int dm_test_serial(struct unit_test_state *uts)
 	 * test with default config which is the only one supported by
 	 * sandbox_serial driver
 	 */
-	ut_assertok(serial_setconfig(SERIAL_DEFAULT_CONFIG));
-	ut_assertok(serial_getconfig(&value_serial));
+	ut_assertok(serial_setconfig(dev_serial, SERIAL_DEFAULT_CONFIG));
+	ut_assertok(serial_getconfig(dev_serial, &value_serial));
 	ut_assert(value_serial == SERIAL_DEFAULT_CONFIG);
-	ut_assertok(serial_getinfo(&info_serial));
+	ut_assertok(serial_getinfo(dev_serial, &info_serial));
 	ut_assert(info_serial.type == SERIAL_CHIP_UNKNOWN);
 	ut_assert(info_serial.addr == SERIAL_DEFAULT_ADDRESS);
 	/*
 	 * test with a parameter which is NULL pointer
 	 */
-	ut_asserteq(-EINVAL, serial_getconfig(NULL));
-	ut_asserteq(-EINVAL, serial_getinfo(NULL));
+	ut_asserteq(-EINVAL, serial_getconfig(dev_serial, NULL));
+	ut_asserteq(-EINVAL, serial_getinfo(dev_serial, NULL));
 	/*
 	 * test with a serial config which is not supported by
 	 * sandbox_serial driver: test with wrong parity
 	 */
 	ut_asserteq(-ENOTSUPP,
-		    serial_setconfig(SERIAL_CONFIG(SERIAL_PAR_ODD,
+		    serial_setconfig(dev_serial,
+				     SERIAL_CONFIG(SERIAL_PAR_ODD,
 						   SERIAL_8_BITS,
 						   SERIAL_ONE_STOP)));
 	/*
@@ -47,7 +48,8 @@ static int dm_test_serial(struct unit_test_state *uts)
 	 * sandbox_serial driver: test with wrong bits number
 	 */
 	ut_asserteq(-ENOTSUPP,
-		    serial_setconfig(SERIAL_CONFIG(SERIAL_PAR_NONE,
+		    serial_setconfig(dev_serial,
+				     SERIAL_CONFIG(SERIAL_PAR_NONE,
 						   SERIAL_6_BITS,
 						   SERIAL_ONE_STOP)));
 
@@ -56,7 +58,8 @@ static int dm_test_serial(struct unit_test_state *uts)
 	 * sandbox_serial driver: test with wrong stop bits number
 	 */
 	ut_asserteq(-ENOTSUPP,
-		    serial_setconfig(SERIAL_CONFIG(SERIAL_PAR_NONE,
+		    serial_setconfig(dev_serial,
+				     SERIAL_CONFIG(SERIAL_PAR_NONE,
 						   SERIAL_8_BITS,
 						   SERIAL_TWO_STOP)));
 

+ 2 - 1
test/py/tests/test_bind.py

@@ -13,7 +13,8 @@ def in_tree(response, name, uclass, drv, depth, last_child):
 	else:
 		leaf = leaf + '`'
 	leaf = leaf + '-- ' + name
-	line = ' *{:10.10}  [0-9]*  \[ [ +] \]   {:20.20}  {}$'.format(uclass, drv, leaf)
+	line = (' *{:10.10}   [0-9]*  \[ [ +] \]   {:20.20}  {}$'
+	        .format(uclass, drv, leaf))
 	prog = re.compile(line)
 	for l in lines:
 		if prog.match(l):

+ 10 - 2
tools/buildman/README

@@ -1046,6 +1046,16 @@ value for 'altbootcmd', but lost one for ' altbootcmd'.
 
 The -U option uses the u-boot.env files which are produced by a build.
 
+
+Building with clang
+===================
+
+To build with clang (sandbox only), use the -O option to override the
+toolchain. For example:
+
+   buildman -O clang-7 --board sandbox
+
+
 Other options
 =============
 
@@ -1169,8 +1179,6 @@ access to log files. Also it would be nice if buildman could 'hunt' for
 problems, perhaps by building a few boards for each arch, or checking
 commits for changed files and building only boards which use those files.
 
-A specific problem to fix is that Ctrl-C does not exit buildman cleanly when
-multiple builder threads are active.
 
 Credits
 =======

+ 7 - 1
tools/buildman/builderthread.py

@@ -156,7 +156,12 @@ class BuilderThread(threading.Thread):
         if result.already_done:
             # Get the return code from that build and use it
             with open(done_file, 'r') as fd:
-                result.return_code = int(fd.readline())
+                try:
+                    result.return_code = int(fd.readline())
+                except ValueError:
+                    # The file may be empty due to running out of disk space.
+                    # Try a rebuild
+                    result.return_code = RETURN_CODE_RETRY
 
             # Check the signal that the build needs to be retried
             if result.return_code == RETURN_CODE_RETRY:
@@ -224,6 +229,7 @@ class BuilderThread(threading.Thread):
                 config_args = ['%s_defconfig' % brd.target]
                 config_out = ''
                 args.extend(self.builder.toolchains.GetMakeArguments(brd))
+                args.extend(self.toolchain.MakeArgs())
 
                 # If we need to reconfigure, do that now
                 if do_config:

+ 2 - 0
tools/buildman/cmdline.py

@@ -74,6 +74,8 @@ def ParseArgs():
     parser.add_option('-o', '--output-dir', type='string',
           dest='output_dir', default='..',
           help='Directory where all builds happen and buildman has its workspace (default is ../)')
+    parser.add_option('-O', '--override-toolchain', type='string',
+          help="Override host toochain to use for sandbox (e.g. 'clang-7')")
     parser.add_option('-Q', '--quick', action='store_true',
           default=False, help='Do a rough build, with limited warning resolution')
     parser.add_option('-p', '--full-path', action='store_true',

+ 1 - 1
tools/buildman/control.py

@@ -141,7 +141,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
 
     no_toolchains = toolchains is None
     if no_toolchains:
-        toolchains = toolchain.Toolchains()
+        toolchains = toolchain.Toolchains(options.override_toolchain)
 
     if options.fetch_arch:
         if options.fetch_arch == 'list':

+ 36 - 6
tools/buildman/toolchain.py

@@ -54,9 +54,11 @@ class Toolchain:
         arch: Architecture of toolchain as determined from the first
                 component of the filename. E.g. arm-linux-gcc becomes arm
         priority: Toolchain priority (0=highest, 20=lowest)
+        override_toolchain: Toolchain to use for sandbox, overriding the normal
+                one
     """
     def __init__(self, fname, test, verbose=False, priority=PRIORITY_CALC,
-                 arch=None):
+                 arch=None, override_toolchain=None):
         """Create a new toolchain object.
 
         Args:
@@ -68,6 +70,7 @@ class Toolchain:
         """
         self.gcc = fname
         self.path = os.path.dirname(fname)
+        self.override_toolchain = override_toolchain
 
         # Find the CROSS_COMPILE prefix to use for U-Boot. For example,
         # 'arm-linux-gnueabihf-gcc' turns into 'arm-linux-gnueabihf-'.
@@ -81,6 +84,8 @@ class Toolchain:
             self.arch = arch
         else:
             self.arch = self.cross[:pos] if pos != -1 else 'sandbox'
+        if self.arch == 'sandbox' and override_toolchain:
+            self.gcc = override_toolchain
 
         env = self.MakeEnvironment(False)
 
@@ -130,8 +135,8 @@ class Toolchain:
     def GetWrapper(self, show_warning=True):
         """Get toolchain wrapper from the setting file.
         """
-	value = ''
-	for name, value in bsettings.GetItems('toolchain-wrapper'):
+        value = ''
+        for name, value in bsettings.GetItems('toolchain-wrapper'):
             if not value:
                 print "Warning: Wrapper not found"
         if value:
@@ -150,11 +155,18 @@ class Toolchain:
         Args:
             full_path: Return the full path in CROSS_COMPILE and don't set
                 PATH
+        Returns:
+            Dict containing the environemnt to use. This is based on the current
+            environment, with changes as needed to CROSS_COMPILE, PATH and
+            LC_ALL.
         """
         env = dict(os.environ)
         wrapper = self.GetWrapper()
 
-        if full_path:
+        if self.override_toolchain:
+            # We'll use MakeArgs() to provide this
+            pass
+        elif full_path:
             env['CROSS_COMPILE'] = wrapper + os.path.join(self.path, self.cross)
         else:
             env['CROSS_COMPILE'] = wrapper + self.cross
@@ -164,6 +176,22 @@ class Toolchain:
 
         return env
 
+    def MakeArgs(self):
+        """Create the 'make' arguments for a toolchain
+
+        This is only used when the toolchain is being overridden. Since the
+        U-Boot Makefile sets CC and HOSTCC explicitly we cannot rely on the
+        environment (and MakeEnvironment()) to override these values. This
+        function returns the arguments to accomplish this.
+
+        Returns:
+            List of arguments to pass to 'make'
+        """
+        if self.override_toolchain:
+            return ['HOSTCC=%s' % self.override_toolchain,
+                    'CC=%s' % self.override_toolchain]
+        return []
+
 
 class Toolchains:
     """Manage a list of toolchains for building U-Boot
@@ -180,10 +208,11 @@ class Toolchains:
         paths: List of paths to check for toolchains (may contain wildcards)
     """
 
-    def __init__(self):
+    def __init__(self, override_toolchain=None):
         self.toolchains = {}
         self.prefixes = {}
         self.paths = []
+        self.override_toolchain = override_toolchain
         self._make_flags = dict(bsettings.GetItems('make-flags'))
 
     def GetPathList(self, show_warning=True):
@@ -234,7 +263,8 @@ class Toolchains:
             priority: Priority to use for this toolchain
             arch: Toolchain architecture, or None if not known
         """
-        toolchain = Toolchain(fname, test, verbose, priority, arch)
+        toolchain = Toolchain(fname, test, verbose, priority, arch,
+                              self.override_toolchain)
         add_it = toolchain.ok
         if toolchain.arch in self.toolchains:
             add_it = (toolchain.priority <