aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux')
-rw-r--r--target/linux/adm5120-2.6/config/default1
-rw-r--r--target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c645
-rw-r--r--target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c13
-rw-r--r--target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c5
-rw-r--r--target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c68
-rw-r--r--target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c23
-rw-r--r--target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c26
-rw-r--r--target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h75
-rw-r--r--target/linux/adm5120-2.6/image/lzma-loader/Makefile2
-rw-r--r--target/linux/adm5120-2.6/patches/001-adm5120.patch44
10 files changed, 694 insertions, 208 deletions
diff --git a/target/linux/adm5120-2.6/config/default b/target/linux/adm5120-2.6/config/default
index 04e7ece691c..1643d5bd5dc 100644
--- a/target/linux/adm5120-2.6/config/default
+++ b/target/linux/adm5120-2.6/config/default
@@ -178,6 +178,7 @@ CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_MYLOADER_PARTS=y
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_SLRAM is not set
CONFIG_NETFILTER_XT_MATCH_QUOTA=m
diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c
index 1780a5bb8af..2ba21b89208 100644
--- a/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c
+++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c
@@ -14,81 +14,339 @@
#include <linux/autoconf.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/string.h>
#include <asm/bootinfo.h>
#include <asm/addrspace.h>
-#include <adm5120_info.h>
-#include <adm5120_defs.h>
-#include <adm5120_switch.h>
-#include <myloader.h>
+#include <asm/mach-adm5120/adm5120_defs.h>
+#include <asm/mach-adm5120/adm5120_switch.h>
+#include <asm/mach-adm5120/adm5120_info.h>
+#include <asm/mach-adm5120/myloader.h>
+#include <asm/mach-adm5120/routerboot.h>
+#include <asm/mach-adm5120/zynos.h>
-/* boot loaders specific definitions */
-#define CFE_EPTSEAL 0x43464531 /* CFE1 is the magic number to recognize CFE from other bootloaders */
+/*
+ * Globals
+ */
+struct adm5120_board adm5120_board;
+unsigned int adm5120_boot_loader;
-struct adm5120_info adm5120_info = {
- .cpu_speed = CPU_SPEED_175,
- .cpu_package = CPU_PACKAGE_PQFP,
- .boot_loader = BOOT_LOADER_UNKNOWN,
- .board_type = BOARD_TYPE_UNKNOWN
-};
+unsigned int adm5120_product_code;
+unsigned int adm5120_revision;
+unsigned int adm5120_package;
+unsigned int adm5120_nand_boot;
+unsigned long adm5120_speed;
+/*
+ * Locals
+ */
static char *boot_loader_names[BOOT_LOADER_LAST+1] = {
[BOOT_LOADER_UNKNOWN] = "Unknown",
[BOOT_LOADER_CFE] = "CFE",
[BOOT_LOADER_UBOOT] = "U-Boot",
[BOOT_LOADER_MYLOADER] = "MyLoader",
- [BOOT_LOADER_ROUTERBOOT]= "RouterBOOT"
+ [BOOT_LOADER_ROUTERBOOT]= "RouterBOOT",
+ [BOOT_LOADER_BOOTBASE] = "Bootbase"
};
-/*
- * CPU settings detection
- */
-#define CODE_GET_PC(c) ((c) & CODE_PC_MASK)
-#define CODE_GET_REV(c) (((c) >> CODE_REV_SHIFT) & CODE_REV_MASK)
-#define CODE_GET_PK(c) (((c) >> CODE_PK_SHIFT) & CODE_PK_MASK)
-#define CODE_GET_CLKS(c) (((c) >> CODE_CLKS_SHIFT) & CODE_CLKS_MASK)
-#define CODE_GET_NAB(c) (((c) & CODE_NAB) != 0)
+static struct adm5120_board __initdata adm5120_boards[] = {
+ {
+ .name = "Compex NetPassage 27G",
+ .mach_type = MACH_ADM5120_NP27G,
+ .has_usb = 1,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Compex NetPassage 28G",
+ .mach_type = MACH_ADM5120_NP28G,
+ .has_usb = 0,
+ .iface_num = 4,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Compex NP28G (HotSpot)",
+ .mach_type = MACH_ADM5120_NP28GHS,
+ .has_usb = 0,
+ .iface_num = 4,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Compex WP54AG",
+ .mach_type = MACH_ADM5120_WP54AG,
+ .has_usb = 0,
+ .iface_num = 2,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Compex WP54G",
+ .mach_type = MACH_ADM5120_WP54G,
+ .has_usb = 0,
+ .iface_num = 2,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Compex WP54G-WRT",
+ .mach_type = MACH_ADM5120_WP54G_WRT,
+ .has_usb = 0,
+ .iface_num = 2,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Compex WP54G v1C",
+ .mach_type = MACH_ADM5120_WP54Gv1C,
+ .has_usb = 0,
+ .iface_num = 2,
+ .flash0_size = 2*1024*1024,
+ },
+ {
+ .name = "Compex WPP54AG",
+ .mach_type = MACH_ADM5120_WPP54AG,
+ .has_usb = 0,
+ .iface_num = 2,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Compex WPP54G",
+ .mach_type = MACH_ADM5120_WPP54G,
+ .has_usb = 0,
+ .iface_num = 2,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "RouterBOARD RB-111",
+ .mach_type = MACH_ADM5120_RB_111,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 128*1024,
+ },
+ {
+ .name = "RouterBOARD RB-112",
+ .mach_type = MACH_ADM5120_RB_112,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 128*1024,
+ },
+ {
+ .name = "RouterBOARD RB-133",
+ .mach_type = MACH_ADM5120_RB_133,
+ .has_usb = 0,
+ .iface_num = 3,
+ .flash0_size = 128*1024,
+ },
+ {
+ .name = "RouterBOARD RB-133C",
+ .mach_type = MACH_ADM5120_RB_133C,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 128*1024,
+ },
+ {
+ .name = "RouterBOARD RB-150",
+ .mach_type = MACH_ADM5120_RB_150,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 128*1024,
+ },
+ {
+ .name = "RouterBOARD RB-153",
+ .mach_type = MACH_ADM5120_RB_153,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 128*1024,
+ },
+ {
+ .name = "ZyXEL HomeSafe 100/100W",
+ .mach_type = MACH_ADM5120_HS100,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 334",
+ .mach_type = MACH_ADM5120_P334,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 2*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 334U",
+ .mach_type = MACH_ADM5120_P334U,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 334W",
+ .mach_type = MACH_ADM5120_P334W,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 2*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 334WH",
+ .mach_type = MACH_ADM5120_P334WH,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 334WHD",
+ .mach_type = MACH_ADM5120_P334WHD,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 334WT",
+ .mach_type = MACH_ADM5120_P334WT,
+ .has_usb = 1,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 335/335WT",
+ .mach_type = MACH_ADM5120_P335,
+ .has_usb = 1,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 335Plus",
+ .mach_type = MACH_ADM5120_P335PLUS,
+ .has_usb = 1,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL Prestige 335U",
+ .mach_type = MACH_ADM5120_P335U,
+ .has_usb = 1,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Unknown ADM5120 board",
+ .mach_type = MACH_ADM5120_UNKNOWN,
+ .has_usb = 1,
+ .iface_num = 5,
+ .flash0_size = 0,
+ }
+};
-static void __init detect_cpu_info(void)
-{
- uint32_t *reg;
- uint32_t code;
- uint32_t clks;
+struct mylo_board {
+ u16 vid;
+ u16 did;
+ u16 svid;
+ u16 sdid;
+ unsigned long mach_type;
+};
- reg = (uint32_t *)KSEG1ADDR(ADM5120_SWITCH_BASE+SWITCH_REG_CODE);
- code = *reg;
+#define DUMMY_BOARD() {.mach_type = MACH_ADM5120_UNKNOWN}
- clks = CODE_GET_CLKS(code);
+#define MYLO_BOARD(v,d,sv,sd,mt) { .vid = (v), .did = (d), .svid = (sv), \
+ .sdid = (sd), .mach_type = (mt) }
- adm5120_info.product_code = CODE_GET_PC(code);
- adm5120_info.revision = CODE_GET_REV(code);
+#define COMPEX_BOARD(d,mt) MYLO_BOARD(VENID_COMPEX,(d),VENID_COMPEX,(d),(mt))
- adm5120_info.cpu_speed = CPU_SPEED_175;
- if (clks & 1)
- adm5120_info.cpu_speed += 25000000;
- if (clks & 2)
- adm5120_info.cpu_speed += 50000000;
+static struct mylo_board __initdata mylo_boards[] = {
+ COMPEX_BOARD(DEVID_COMPEX_NP27G, MACH_ADM5120_NP27G),
+ COMPEX_BOARD(DEVID_COMPEX_NP28G, MACH_ADM5120_NP28G),
+ COMPEX_BOARD(DEVID_COMPEX_NP28GHS, MACH_ADM5120_NP28GHS),
+ COMPEX_BOARD(DEVID_COMPEX_WP54G, MACH_ADM5120_WP54G),
+ COMPEX_BOARD(DEVID_COMPEX_WP54Gv1C, MACH_ADM5120_WP54Gv1C),
+ COMPEX_BOARD(DEVID_COMPEX_WP54AG, MACH_ADM5120_WP54AG),
+ COMPEX_BOARD(DEVID_COMPEX_WPP54G, MACH_ADM5120_WPP54G),
+ COMPEX_BOARD(DEVID_COMPEX_WPP54AG, MACH_ADM5120_WPP54AG),
+ DUMMY_BOARD()
+};
+
+#define ROUTERBOARD_NAME_LEN 16
+
+struct routerboard {
+ unsigned long mach_type;
+ char name[ROUTERBOARD_NAME_LEN];
+};
+
+#define ROUTERBOARD(n, mt) { .name = (n), .mach_type = (mt) }
+static struct routerboard __initdata routerboards[] = {
+ ROUTERBOARD("111", MACH_ADM5120_RB_111),
+ ROUTERBOARD("112", MACH_ADM5120_RB_112),
+ ROUTERBOARD("133", MACH_ADM5120_RB_133),
+ ROUTERBOARD("133C", MACH_ADM5120_RB_133C),
+ ROUTERBOARD("miniROUTER", MACH_ADM5120_RB_150),
+ ROUTERBOARD("153", MACH_ADM5120_RB_150),
+ DUMMY_BOARD()
+};
+
+struct zynos_board {
+ unsigned long mach_type;
+ unsigned int vendor_id;
+ u16 board_id;
+};
+
+#define ZYNOS_VENDOR_ID_INVALID 0
+#define ZYNOS_VENDOR_ID_ZYXEL 1
+#define ZYNOS_VENDOR_ID_DLINK 2
+#define ZYNOS_VENDOR_ID_LUCENT 3
+
+#define ZYNOS_BOARD(vi, bi, mt) { .vendor_id = (vi), .board_id = (bi), \
+ .mach_type = (mt) }
+
+#define ZYXEL_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_ZYXEL, bi, mt)
+#define DLINK_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_DLINK, bi, mt)
+#define LUCENT_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_LUCENT, bi, mt)
+
+static struct zynos_board __initdata zynos_boards[] = {
+ ZYXEL_BOARD(ZYNOS_BOARD_HS100, MACH_ADM5120_HS100),
+ ZYXEL_BOARD(ZYNOS_BOARD_P334, MACH_ADM5120_P334),
+ ZYXEL_BOARD(ZYNOS_BOARD_P334U, MACH_ADM5120_P334U),
+ ZYXEL_BOARD(ZYNOS_BOARD_P334W, MACH_ADM5120_P334W),
+ ZYXEL_BOARD(ZYNOS_BOARD_P334WH, MACH_ADM5120_P334WH),
+ ZYXEL_BOARD(ZYNOS_BOARD_P334WHD, MACH_ADM5120_P334WHD),
+ ZYXEL_BOARD(ZYNOS_BOARD_P334WT, MACH_ADM5120_P334WT),
+ ZYXEL_BOARD(ZYNOS_BOARD_P335, MACH_ADM5120_P335),
+ ZYXEL_BOARD(ZYNOS_BOARD_P335PLUS, MACH_ADM5120_P335PLUS),
+ ZYXEL_BOARD(ZYNOS_BOARD_P335U, MACH_ADM5120_P335U),
+ DUMMY_BOARD()
+};
+
+/*
+ * Helper routines
+ */
+static inline u16 read_le16(void *buf)
+{
+ u8 *p;
- adm5120_info.cpu_package = (CODE_GET_PK(code) == CODE_PK_BGA) ?
- CPU_PACKAGE_BGA : CPU_PACKAGE_PQFP;
+ p = buf;
+ return ((u16)p[0] + ((u16)p[1] << 8));
+}
- adm5120_info.nand_boot = CODE_GET_NAB(code);
+static inline u32 read_le32(void *buf)
+{
+ u8 *p;
+ p = buf;
+ return ((u32)p[0] + ((u32)p[1] << 8) + ((u32)p[2] << 16) +
+ ((u32)p[3] << 24));
}
/*
- * Boot loader detection routines
+ * CFE based boards
*/
-static int __init detect_cfe(void)
+#define CFE_EPTSEAL 0x43464531 /* CFE1 is the magic number to recognize CFE
+from other bootloaders */
+
+static int __init cfe_present(void)
{
/*
* This method only works, when we are booted directly from the CFE.
*/
- uint32_t cfe_handle = (uint32_t) fw_arg0;
- uint32_t cfe_a1_val = (uint32_t) fw_arg1;
- uint32_t cfe_entry = (uint32_t) fw_arg2;
- uint32_t cfe_seal = (uint32_t) fw_arg3;
+ u32 cfe_handle = (u32) fw_arg0;
+ u32 cfe_a1_val = (u32) fw_arg1;
+ u32 cfe_entry = (u32) fw_arg2;
+ u32 cfe_seal = (u32) fw_arg3;
/* Check for CFE by finding the CFE magic number */
if (cfe_seal != CFE_EPTSEAL) {
@@ -96,7 +354,8 @@ static int __init detect_cfe(void)
return 0;
}
- /* cfe_a1_val must be 0, because only one CPU present in the ADM5120 SoC */
+ /* cfe_a1_val must be 0, because only one CPU present in the ADM5120 SoC
+*/
if (cfe_a1_val != 0) {
return 0;
}
@@ -109,88 +368,294 @@ static int __init detect_cfe(void)
return 1;
}
-static int __init detect_uboot(void)
+static unsigned long __init cfe_detect_board(void)
{
- /* FIXME: not yet implemented */
- return 0;
+ return MACH_ADM5120_WP54G_WRT;
}
-static int __init detect_myloader(void)
+/*
+ * MyLoader based boards
+ */
+#define SYS_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F000)
+#define BOARD_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F800)
+#define PART_TABLE_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x10000)
+
+static unsigned long __init myloader_detect_board(void)
{
struct mylo_system_params *sysp;
struct mylo_board_params *boardp;
struct mylo_partition_table *parts;
+ struct mylo_board *board;
+ unsigned long ret;
+
+ ret = MACH_ADM5120_UNKNOWN;
- sysp = (struct mylo_system_params *)(MYLO_MIPS_SYS_PARAMS);
- boardp = (struct mylo_board_params *)(MYLO_MIPS_BOARD_PARAMS);
- parts = (struct mylo_partition_table *)(MYLO_MIPS_PARTITIONS);
+ sysp = (struct mylo_system_params *)(SYS_PARAMS_ADDR);
+ boardp = (struct mylo_board_params *)(BOARD_PARAMS_ADDR);
+ parts = (struct mylo_partition_table *)(PART_TABLE_ADDR);
/* Check for some magic numbers */
- if ((sysp->magic != MYLO_MAGIC_SYS_PARAMS) ||
- (boardp->magic != MYLO_MAGIC_BOARD_PARAMS) ||
- (parts->magic != MYLO_MAGIC_PARTITIONS))
- return 0;
+ if ((le32_to_cpu(sysp->magic) != MYLO_MAGIC_SYS_PARAMS) ||
+ (le32_to_cpu(boardp->magic) != MYLO_MAGIC_BOARD_PARAMS) ||
+ (le32_to_cpu(parts->magic) != MYLO_MAGIC_PARTITIONS))
+ goto out;
+
+ for (board = mylo_boards; board->mach_type != MACH_ADM5120_UNKNOWN;
+ board++) {
+ if ((le16_to_cpu(sysp->vid) == board->vid) &&
+ (le16_to_cpu(sysp->did) == board->did) &&
+ (le16_to_cpu(sysp->svid) == board->svid) &&
+ (le16_to_cpu(sysp->sdid) == board->sdid)) {
+ ret = board->mach_type;
+ break;
+ }
+ }
- return 1;
+ /* assume MyLoader as the boot-loader */
+ adm5120_boot_loader = BOOT_LOADER_MYLOADER;
+
+out:
+ return ret;
+}
+
+/*
+ * RouterBOOT based boards
+ */
+static int __init routerboot_find_tag(u8 *buf, u16 tagid, void **tagval,
+ u16 *taglen)
+{
+ u16 id,len;
+ int ret;
+
+ ret = -1;
+ /* skip header */
+ buf += 8;
+ for (;;) {
+ id = read_le16(buf);
+ buf += 2;
+ if (id == RB_ID_TERMINATOR)
+ break;
+
+ len = read_le16(buf);
+ buf += 2;
+ if (id == tagid) {
+ *tagval = buf;
+ *taglen = len;
+ ret = 0;
+ break;
+ }
+
+ buf += len;
+ }
+
+ return ret;
}
-static int __init detect_routerboot(void)
+#define RB_HS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x1000)
+#define RB_SS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x2000)
+#define RB_FW_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x10000)
+
+static unsigned long __init routerboot_detect_board(void)
+{
+ struct routerboard *board;
+ u32 magic;
+ char *name;
+ u16 namelen;
+ unsigned long ret;
+
+ ret = MACH_ADM5120_UNKNOWN;
+
+ magic = le32_to_cpu(*(u32 *)RB_HS_ADDR);
+ if (magic != RB_MAGIC_HARD)
+ goto out;
+
+ magic = le32_to_cpu(*(u32 *)RB_SS_ADDR);
+ if ((magic != RB_MAGIC_SOFT) && (magic != RB_MAGIC_DAWN))
+ goto out;
+
+ if (routerboot_find_tag((u8 *)RB_HS_ADDR, RB_ID_BOARD_NAME,
+ (void *)&name, &namelen))
+ goto out;
+
+ for (board = routerboards; board->mach_type != MACH_ADM5120_UNKNOWN;
+ board++) {
+ if (strncmp(board->name, name, strlen(board->name)) == 0) {
+ ret = board->mach_type;
+ break;
+ }
+
+ }
+
+ /* assume RouterBOOT as the boot-loader */
+ adm5120_boot_loader = BOOT_LOADER_ROUTERBOOT;
+
+out:
+ return ret;
+}
+
+/*
+ * ZyNOS based boards
+ */
+#define CHECK_VENDOR(n) (strnicmp(vendor, ZYNOS_VENDOR_ZYXEL, \
+ strlen(ZYNOS_VENDOR_ZYXEL)) == 0)
+
+static unsigned int __init zynos_get_vendor_id(unsigned char *vendor)
+{
+ int ret;
+
+ ret = ZYNOS_VENDOR_ID_INVALID;
+
+ if CHECK_VENDOR(ZYNOS_VENDOR_ZYXEL)
+ ret = ZYNOS_VENDOR_ID_ZYXEL;
+#if 0
+ /* TODO: there are no known ADM5120 based boards from other vendors */
+ else if CHECK_VENDOR(ZYNOS_VENDOR_DLINK)
+ ret = ZYNOS_VENDOR_ID_DLINK;
+ else if CHECK_VENDOR(ZYNOS_VENDOR_LUCENT)
+ ret = ZYNOS_VENDOR_ID_LUCENT;
+#endif
+
+ return ret;
+}
+
+#define ZYNOS_INFO_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x3F90)
+#define BOOTEXT_ADDR_2M 0xBFC08000
+#define BOOTEXT_ADDR_4M 0xBFC10000
+
+static unsigned long __init zynos_detect_board(void)
+{
+ struct zynos_board_info *info;
+ struct zynos_board *board;
+ unsigned int vendor_id;
+ u32 bootext_addr;
+ unsigned long ret;
+
+ ret = MACH_ADM5120_UNKNOWN;
+
+ info = (struct zynos_board_info *)(ZYNOS_INFO_ADDR);
+ vendor_id = zynos_get_vendor_id(&info->vendor);
+ if (vendor_id == ZYNOS_VENDOR_ID_INVALID)
+ goto out;
+
+ bootext_addr = be32_to_cpu(info->bootext_addr);
+ if ((bootext_addr != BOOTEXT_ADDR_2M) ||
+ (bootext_addr != BOOTEXT_ADDR_4M))
+ goto out;
+
+ for (board = zynos_boards; board->mach_type != MACH_ADM5120_UNKNOWN;
+ board++) {
+ if ((board->vendor_id == vendor_id) &&
+ (board->board_id == be16_to_cpu(info->board_id))) {
+ ret = board->mach_type;
+ break;
+ }
+ }
+
+ /* assume Bootbase as the boot-loader */
+ adm5120_boot_loader = BOOT_LOADER_BOOTBASE;
+
+out:
+ return ret;
+}
+
+/*
+ * U-Boot based boards
+ */
+static int __init uboot_present(void)
{
/* FIXME: not yet implemented */
return 0;
}
-static int __init detect_bootloader(void)
+static unsigned long __init uboot_detect_board(void)
+{
+ /* FIXME: not yet implemented */
+ return MACH_ADM5120_UNKNOWN;
+}
+
+static void __init adm5120_detect_board(void)
{
- if (detect_cfe())
- return BOOT_LOADER_CFE;
+ struct adm5120_board *board;
+ unsigned long t;
+
+ adm5120_boot_loader = BOOT_LOADER_UNKNOWN;
- if (detect_uboot())
- return BOOT_LOADER_UBOOT;
+ /* Try to detect board type without bootloader */
+ t = routerboot_detect_board();
- if (detect_myloader())
- return BOOT_LOADER_MYLOADER;
+ if (t == MACH_ADM5120_UNKNOWN)
+ t = zynos_detect_board();
- if (detect_routerboot())
- return BOOT_LOADER_ROUTERBOOT;
+ if (t == MACH_ADM5120_UNKNOWN)
+ t = myloader_detect_board();
+
+ /* Try to detect bootloader type */
+ if (cfe_present()) {
+ adm5120_boot_loader = BOOT_LOADER_CFE;
+ if (t == MACH_ADM5120_UNKNOWN)
+ t = cfe_detect_board();
+ } else if (uboot_present()) {
+ adm5120_boot_loader = BOOT_LOADER_UBOOT;
+ if (t == MACH_ADM5120_UNKNOWN)
+ t = uboot_detect_board();
+ }
- return BOOT_LOADER_UNKNOWN;
+ for (board = adm5120_boards; board->mach_type != MACH_ADM5120_UNKNOWN;
+ board++) {
+ if (board->mach_type == t)
+ break;
+ }
+
+ memcpy(&adm5120_board, board, sizeof(adm5120_board));
}
/*
- * Board detection
+ * CPU settings detection
*/
-static void __init detect_board_type(void)
+#define CODE_GET_PC(c) ((c) & CODE_PC_MASK)
+#define CODE_GET_REV(c) (((c) >> CODE_REV_SHIFT) & CODE_REV_MASK)
+#define CODE_GET_PK(c) (((c) >> CODE_PK_SHIFT) & CODE_PK_MASK)
+#define CODE_GET_CLKS(c) (((c) >> CODE_CLKS_SHIFT) & CODE_CLKS_MASK)
+#define CODE_GET_NAB(c) (((c) & CODE_NAB) != 0)
+
+static void __init adm5120_detect_cpuinfo(void)
{
- switch(adm5120_info.boot_loader) {
- case BOOT_LOADER_CFE:
- adm5120_info.board_type = BOARD_TYPE_WP54G_WRT;
- adm5120_info.iface_num = 2;
- adm5120_info.has_usb = 0;
- printk("Board is a Compex WP54G-WRT\n");
- default:
- adm5120_info.board_type = BOARD_TYPE_UNKNOWN;
- printk("Board type is unknown\n");
- }
+ u32 code;
+ u32 clks;
+
+ code = *(u32 *)KSEG1ADDR(ADM5120_SWITCH_BASE+SWITCH_REG_CODE);
+
+ adm5120_product_code = CODE_GET_PC(code);
+ adm5120_revision = CODE_GET_REV(code);
+ adm5120_package = (CODE_GET_PK(code) == CODE_PK_BGA) ?
+ ADM5120_PACKAGE_BGA : ADM5120_PACKAGE_PQFP;
+ adm5120_nand_boot = CODE_GET_NAB(code);
+
+ clks = CODE_GET_CLKS(code);
+ adm5120_speed = ADM5120_SPEED_175;
+ if (clks & 1)
+ adm5120_speed += 25000000;
+ if (clks & 2)
+ adm5120_speed += 50000000;
}
void __init adm5120_info_show(void)
{
+ /* FIXME: move this somewhere else */
printk("ADM%04X%s revision %d, running at %ldMHz\n",
- adm5120_info.product_code,
- (adm5120_info.cpu_package == CPU_PACKAGE_BGA) ? "" : "P",
- adm5120_info.revision,
- (adm5120_info.cpu_speed / 1000000)
+ adm5120_product_code,
+ (adm5120_package == ADM5120_PACKAGE_BGA) ? "" : "P",
+ adm5120_revision, (adm5120_speed / 1000000)
);
- printk("Boot loader is: %s\n", boot_loader_names[adm5120_info.boot_loader]);
- printk("Booted from : %s flash\n", adm5120_info.nand_boot ? "NAND" : "NOR");
+ printk("Boot loader is: %s\n", boot_loader_names[adm5120_boot_loader]);
+ printk("Booted from : %s flash\n", adm5120_nand_boot ? "NAND":"NOR");
+ printk("Board is : %s\n", adm5120_board_name());
}
void __init adm5120_info_init(void)
{
- detect_cpu_info();
- adm5120_info.boot_loader = detect_bootloader();
- detect_board_type();
+ adm5120_detect_cpuinfo();
+ adm5120_detect_board();
adm5120_info_show();
}
diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c
index e16ac65001f..63e5b8602c3 100644
--- a/target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c
+++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/prom.c
@@ -3,6 +3,7 @@
* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) 2003 ADMtek Incorporated.
* daniell@admtek.com.tw
+ * Copyright (C) 2007 OpenWrt.org
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
@@ -29,7 +30,7 @@
#include <asm/bootinfo.h>
#include <asm/addrspace.h>
-#include <adm5120_info.h>
+#include <asm/mach-adm5120/adm5120_info.h>
void setup_prom_printf(int);
void prom_printf(char *, ...);
@@ -98,18 +99,18 @@ char *prom_getenv(char *envname)
return(NULL);
}
-
+
/*
* initialize the prom module.
*/
void __init prom_init(void)
{
- /* you should these macros defined in include/asm/bootinfo.h */
- mips_machgroup = MACH_GROUP_ADM_GW;
- mips_machtype = MACH_ADM_GW_5120;
-
adm5120_info_init();
+ /* you should these macros defined in include/asm/bootinfo.h */
+ mips_machgroup = MACH_GROUP_ADM5120;
+ mips_machtype = adm5120_board.mach_type;
+
/* init command line, register a default kernel command line */
strcpy(&(arcs_cmdline[0]), CONFIG_CMDLINE);
diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c
index 1b99d7799aa..3f4f3656106 100644
--- a/target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c
+++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/setup.c
@@ -3,6 +3,7 @@
* Creator : daniell@admtek.com.tw
* Copyright 1999, 2000 MIPS Technologies, Inc.
* Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005
+ * Copyright (C) 2007 OpenWrt.org
*/
#include <linux/autoconf.h>
@@ -44,7 +45,7 @@ void adm5120_power_off(void)
void __init adm5120_time_init(void)
{
- mips_counter_frequency = adm5120_info.cpu_speed >> 1;
+ mips_counter_frequency = adm5120_speed >> 1;
}
void __init plat_timer_setup(struct irqaction *irq)
@@ -71,7 +72,7 @@ void __init plat_mem_setup(void)
const char *get_system_type(void)
{
- return "ADM5120 Board";
+ return adm5120_board_name();
}
static struct resource adm5120_hcd_resources[] = {
diff --git a/target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c b/target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c
index df506d7fa84..0d95dc833df 100644
--- a/target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c
+++ b/target/linux/adm5120-2.6/files/drivers/mtd/maps/adm5120_mtd.c
@@ -3,7 +3,7 @@
* Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
* Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
*
- * original functions for finding root filesystem from Mike Baker
+ * original functions for finding root filesystem from Mike Baker
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -24,10 +24,10 @@
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
- *
+ *
* Copyright 2001-2003, Broadcom Corporation
* All Rights Reserved.
- *
+ *
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
@@ -57,7 +57,7 @@ extern int parse_myloader_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long origin);
-/* Macros for switching flash bank
+/* Macros for switching flash bank
ADM5120 only support 2MB flash address space
so GPIO5 is used as A20
*/
@@ -69,7 +69,7 @@ extern int parse_myloader_partitions(struct mtd_info *master,
#define TRX_MAGIC 0x30524448 /* "HDR0" */
#define TRX_VERSION 1
#define TRX_MAX_LEN 0x3A0000
-#define TRX_NO_HEADER 1 /* Do not write TRX header */
+#define TRX_NO_HEADER 1 /* Do not write TRX header */
#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
#define TRX_MAX_OFFSET 3
@@ -150,7 +150,7 @@ static void adm5120_map_copy_from(struct map_info *map, void *to, unsigned long
flash_switch_bank(FLASH_BOUNDARY);
inline_map_copy_from(map, to, from, len);
}
-
+
}
static int __init
@@ -172,7 +172,7 @@ find_cfe_size(struct mtd_info *mtd, size_t size)
memset(buf, 0xe5, sizeof(buf));
/*
- * Read into buffer
+ * Read into buffer
*/
if (mtd->read(mtd, off, sizeof(buf), &len, buf) ||
len != sizeof(buf))
@@ -199,7 +199,7 @@ find_cfe_size(struct mtd_info *mtd, size_t size)
* Copied from mtdblock.c
*
* Cache stuff...
- *
+ *
* Since typical flash erasable sectors are much larger than what Linux's
* buffer cache can handle, we must implement read-modify-write on flash
* sectors for each block write requests. To avoid over-erasing flash sectors
@@ -213,7 +213,7 @@ static void erase_callback(struct erase_info *done)
wake_up(wait_q);
}
-static int erase_write (struct mtd_info *mtd, unsigned long pos,
+static int erase_write (struct mtd_info *mtd, unsigned long pos,
int len, const char *buf)
{
struct erase_info erase;
@@ -282,7 +282,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
memset(&trx, 0xe5, sizeof(trx));
/*
- * Read into buffer
+ * Read into buffer
*/
if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) ||
len != sizeof(trx))
@@ -290,9 +290,9 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
/* found a TRX header */
if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
- part->offset = le32_to_cpu(trx.offsets[2]) ? :
+ part->offset = le32_to_cpu(trx.offsets[2]) ? :
le32_to_cpu(trx.offsets[1]);
- part->size = le32_to_cpu(trx.len);
+ part->size = le32_to_cpu(trx.len);
part->size -= part->offset;
part->offset += off;
@@ -309,7 +309,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
found:
if (part->size == 0)
return 0;
-
+
if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
return 0;
@@ -335,7 +335,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
if (trx.len != part->offset + part->size - off) {
/* Update the trx offsets and length */
trx.len = part->offset + part->size - off;
-
+
/* Update the trx crc32 */
for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
@@ -351,7 +351,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
printk("Error accessing the first trx eraseblock\n");
return 0;
}
-
+
printk("Updating TRX offsets and length:\n");
printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32);
printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32);
@@ -366,7 +366,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
kfree(block);
printk("Done\n");
}
-
+
return part->size;
}
@@ -395,15 +395,15 @@ init_mtd_partitions(struct mtd_info *mtd, size_t size)
/* linux (kernel and rootfs) */
if (cfe_size != 384 * 1024) {
adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size;
- adm5120_cfe_parts[1].size = adm5120_cfe_parts[3].offset -
+ adm5120_cfe_parts[1].size = adm5120_cfe_parts[3].offset -
adm5120_cfe_parts[1].offset;
} else {
/* do not count the elf loader, which is on one block */
- adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size +
+ adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size +
adm5120_cfe_parts[3].size + mtd->erasesize;
- adm5120_cfe_parts[1].size = size -
- adm5120_cfe_parts[0].size -
- (2*adm5120_cfe_parts[3].size) -
+ adm5120_cfe_parts[1].size = size -
+ adm5120_cfe_parts[0].size -
+ (2*adm5120_cfe_parts[3].size) -
mtd->erasesize;
}
@@ -411,28 +411,28 @@ init_mtd_partitions(struct mtd_info *mtd, size_t size)
if (find_root(mtd,size,&adm5120_cfe_parts[2])==0) {
/* entirely jffs2 */
adm5120_cfe_parts[4].name = NULL;
- adm5120_cfe_parts[2].size = size - adm5120_cfe_parts[2].offset -
+ adm5120_cfe_parts[2].size = size - adm5120_cfe_parts[2].offset -
adm5120_cfe_parts[3].size;
} else {
/* legacy setup */
/* calculate leftover flash, and assign it to the jffs2 partition */
if (cfe_size != 384 * 1024) {
- adm5120_cfe_parts[4].offset = adm5120_cfe_parts[2].offset +
+ adm5120_cfe_parts[4].offset = adm5120_cfe_parts[2].offset +
adm5120_cfe_parts[2].size;
if ((adm5120_cfe_parts[4].offset % mtd->erasesize) > 0) {
- adm5120_cfe_parts[4].offset += mtd->erasesize -
+ adm5120_cfe_parts[4].offset += mtd->erasesize -
(adm5120_cfe_parts[4].offset % mtd->erasesize);
}
- adm5120_cfe_parts[4].size = adm5120_cfe_parts[3].offset -
+ adm5120_cfe_parts[4].size = adm5120_cfe_parts[3].offset -
adm5120_cfe_parts[4].offset;
} else {
- adm5120_cfe_parts[4].offset = adm5120_cfe_parts[2].offset +
+ adm5120_cfe_parts[4].offset = adm5120_cfe_parts[2].offset +
adm5120_cfe_parts[2].size;
if ((adm5120_cfe_parts[4].offset % mtd->erasesize) > 0) {
- adm5120_cfe_parts[4].offset += mtd->erasesize -
+ adm5120_cfe_parts[4].offset += mtd->erasesize -
(adm5120_cfe_parts[4].offset % mtd->erasesize);
}
- adm5120_cfe_parts[4].size = size - adm5120_cfe_parts[3].size -
+ adm5120_cfe_parts[4].size = size - adm5120_cfe_parts[3].size -
adm5120_cfe_parts[4].offset;
}
}
@@ -460,7 +460,7 @@ int __init init_adm5120_map(void)
adm5120_map.read = adm5120_map_read;
adm5120_map.write = adm5120_map_write;
adm5120_map.copy_from = adm5120_map_copy_from;
-
+
if (!(adm5120_mtd = do_map_probe("cfi_probe", &adm5120_map))) {
printk("Failed to do_map_probe\n");
iounmap((void *)adm5120_map.virt);
@@ -475,14 +475,14 @@ int __init init_adm5120_map(void)
#ifdef CONFIG_MTD_PARTITIONS
- if (adm5120_info.boot_loader == BOOT_LOADER_CFE)
+ if (adm5120_boot_loader == BOOT_LOADER_CFE)
{
printk(KERN_NOTICE "adm5120 : using CFE flash mapping\n");
parts = init_mtd_partitions(adm5120_mtd, size);
-
+
for (i = 0; parts[i].name; i++);
ret = add_mtd_partitions(adm5120_mtd, parts, i);
-
+
if (ret) {
printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
goto fail;
@@ -490,11 +490,11 @@ int __init init_adm5120_map(void)
}
#endif
#ifdef CONFIG_MTD_MYLOADER_PARTS
- if (adm5120_info.boot_loader == BOOT_LOADER_MYLOADER)
+ if (adm5120_boot_loader == BOOT_LOADER_MYLOADER)
{
printk(KERN_NOTICE "adm5120 : using MyLoader flash mapping\n");
char *part_type;
-
+
if (parsed_nr_parts == 0) {
ret = parse_myloader_partitions(adm5120_mtd, &parts, 0);
diff --git a/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c b/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c
index fb1752b631f..1391bbe8c7d 100644
--- a/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c
+++ b/target/linux/adm5120-2.6/files/drivers/net/adm5120sw.c
@@ -3,7 +3,7 @@
*
* Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005
*
- * Inspiration for this driver came from the original ADMtek 2.4
+ * Inspiration for this driver came from the original ADMtek 2.4
* driver, Copyright ADMtek Inc.
*/
#include <linux/autoconf.h>
@@ -20,7 +20,7 @@
#include <asm/io.h>
#include "adm5120sw.h"
-#include "adm5120_info.h"
+#include <asm/mach-adm5120/adm5120_info.h>
MODULE_AUTHOR("Jeroen Vreeken (pe1rxq@amsat.org)");
MODULE_DESCRIPTION("ADM5120 ethernet switch driver");
@@ -29,7 +29,7 @@ MODULE_LICENSE("GPL");
/*
* The ADM5120 uses an internal matrix to determine which ports
* belong to which VLAN.
- * The default generates a VLAN (and device) for each port
+ * The default generates a VLAN (and device) for each port
* (including MII port) and the CPU port is part of all of them.
*
* Another example, one big switch and everything mapped to eth0:
@@ -42,7 +42,7 @@ static unsigned char vlan_matrix[SW_DEVS] = {
static int adm5120_nrdevs;
static struct net_device *adm5120_devs[SW_DEVS];
-static struct adm5120_dma
+static struct adm5120_dma
adm5120_dma_txh_v[ADM5120_DMA_TXH] __attribute__((aligned(16))),
adm5120_dma_txl_v[ADM5120_DMA_TXL] __attribute__((aligned(16))),
adm5120_dma_rxh_v[ADM5120_DMA_RXH] __attribute__((aligned(16))),
@@ -389,14 +389,9 @@ static int __init adm5120_sw_init(void)
if (err)
goto out;
- /* MII port? */
- if (adm5120_get_reg(ADM5120_CODE) & ADM5120_CODE_PQFP)
+ adm5120_nrdevs = adm5120_board.iface_num;
+ if (adm5120_nrdevs > 5 && !adm5120_has_gmii())
adm5120_nrdevs = 5;
- /* CFE based devices only have two enet ports */
- else if (adm5120_info.boot_loader == BOOT_LOADER_CFE)
- adm5120_nrdevs = 2;
- else
- adm5120_nrdevs = 6;
adm5120_set_reg(ADM5120_CPUP_CONF,
ADM5120_DISCCPUPORT | ADM5120_CRC_PADDING |
@@ -426,14 +421,14 @@ static int __init adm5120_sw_init(void)
adm5120_set_reg(ADM5120_RECEIVE_LBADDR, KSEG1ADDR(adm5120_dma_rxl));
adm5120_set_vlan(vlan_matrix);
-
+
for (i=0; i<adm5120_nrdevs; i++) {
adm5120_devs[i] = alloc_etherdev(sizeof(struct adm5120_sw));
if (!adm5120_devs[i]) {
err = -ENOMEM;
goto out_int;
}
-
+
dev = adm5120_devs[i];
SET_MODULE_OWNER(dev);
memset(netdev_priv(dev), 0, sizeof(struct adm5120_sw));
@@ -456,7 +451,7 @@ static int __init adm5120_sw_init(void)
memcpy(dev->dev_addr, "\x00\x50\xfc\x11\x22\x01", 6);
dev->dev_addr[5] += i;
adm5120_write_mac(dev);
-
+
if ((err = register_netdev(dev))) {
free_netdev(dev);
goto out_int;
diff --git a/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c b/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c
index 6f0df78c3a2..25ba4b8b938 100644
--- a/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c
+++ b/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org)
*
- * Based on the ADMtek 2.4 driver
+ * Based on the ADMtek 2.4 driver
* (C) Copyright 2003 Junius Chen <juniusc@admtek.com.tw>
* Which again was based on the ohci and uhci drivers.
*/
@@ -146,7 +146,7 @@ static int admhcd_td_err[16] = {
struct admhcd {
spinlock_t lock;
-
+
void __iomem *addr_reg;
void __iomem *data_reg;
/* Root hub registers */
@@ -160,7 +160,7 @@ struct admhcd {
u32 base;
u32 dma_en;
unsigned long flags;
-
+
};
static inline struct admhcd *hcd_to_admhcd(struct usb_hcd *hcd)
@@ -213,7 +213,7 @@ static struct admhcd_td *admhcd_td_alloc(struct admhcd_ed *ed, struct urb *urb)
if (ed->cur == NULL) {
ed->cur = tdn;
ed->head = tdn;
- ed->tail = tdn;
+ ed->tail = tdn;
td = tdn;
} else {
/* Supply back the old tail and link in new td as tail */
@@ -345,7 +345,7 @@ static irqreturn_t adm5120hcd_irq(int irq, void *ptr, struct pt_regs *regs)
}
if (intstatus & ADMHCD_INT_TD) {
struct admhcd_ed *ed, *head;
-
+
admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_TD);
head = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD);
@@ -355,7 +355,7 @@ static irqreturn_t adm5120hcd_irq(int irq, void *ptr, struct pt_regs *regs)
if (ed->urb && !(ed->cur->control & ADMHCD_TD_OWN)) {
struct admhcd_td *td;
int error;
-
+
td = ed->cur;
error = (td->control & ADMHCD_TD_ERRMASK) >>
ADMHCD_TD_ERRSHIFT;
@@ -442,7 +442,7 @@ static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
td = admhcd_td_fill(ADMHCD_TD_SETUP | ADMHCD_TD_DATA0,
td, (dma_addr_t)urb->setup_packet, 8);
while (data_len > 0) {
- td = admhcd_td_fill(ADMHCD_TD_DATA1
+ td = admhcd_td_fill(ADMHCD_TD_DATA1
| ADMHCD_TD_R |
(usb_pipeout(pipe) ?
ADMHCD_TD_OUT : ADMHCD_TD_IN), td,
@@ -459,7 +459,7 @@ static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
i = 0;
while(data_len > 4096) {
td = admhcd_td_fill((usb_pipeout(pipe) ?
- ADMHCD_TD_OUT :
+ ADMHCD_TD_OUT :
ADMHCD_TD_IN | ADMHCD_TD_R) |
(i ? ADMHCD_TD_TOGGLE : toggle), td,
data, 4096);
@@ -467,7 +467,7 @@ static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
data_len -= 4096;
i++;
}
- td = admhcd_td_fill((usb_pipeout(pipe) ?
+ td = admhcd_td_fill((usb_pipeout(pipe) ?
ADMHCD_TD_OUT : ADMHCD_TD_IN) |
(i ? ADMHCD_TD_TOGGLE : toggle), td, data, data_len);
i++;
@@ -616,7 +616,7 @@ static int admhcd_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case USB_PORT_FEAT_RESET:
if (admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4)
& ADMHCD_CCS) {
- admhcd_reg_set(ahcd,
+ admhcd_reg_set(ahcd,
ADMHCD_REG_PORTSTATUS0 + port*4,
ADMHCD_PRS | ADMHCD_CSC);
mdelay(50);
@@ -707,7 +707,7 @@ static int __init adm5120hcd_probe(struct platform_device *pdev)
struct usb_device *udev;
struct resource *addr, *data;
void __iomem *addr_reg;
- void __iomem *data_reg;
+ void __iomem *data_reg;
int irq, err = 0;
if (pdev->num_resources < 3) {
@@ -748,7 +748,7 @@ static int __init adm5120hcd_probe(struct platform_device *pdev)
err = -ENOMEM;
goto out_mem;
}
-
+
hcd = usb_create_hcd(&adm5120_hc_driver, &pdev->dev, pdev->dev.bus_id);
if (!hcd)
@@ -826,7 +826,7 @@ static int __init adm5120hcd_init(void)
{
if (usb_disabled())
return -ENODEV;
- if (!adm5120_info.has_usb)
+ if (!adm5120_board.has_usb)
return -ENODEV;
return platform_driver_register(&adm5120hcd_driver);
diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h
index 3e0acba329b..dbb02cf8ed7 100644
--- a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h
+++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h
@@ -15,59 +15,56 @@
#include <linux/types.h>
-struct adm5120_info {
- unsigned int product_code;
- unsigned int revision;
- unsigned int cpu_package;
- unsigned int nand_boot;
- unsigned long cpu_speed;
- unsigned int boot_loader;
- unsigned int board_type;
- unsigned int iface_num; /* Number of Ethernet interfaces */
- unsigned int has_usb; /* USB controller presence flag */
- u32 window_addr; /* Flash address */
- u32 window_size; /* Flash size */
-};
+#define ADM5120_BOARD_NAMELEN 64
-#define CPU_SPEED_175 175000000
-#define CPU_SPEED_200 200000000
-#define CPU_SPEED_225 225000000
-#define CPU_SPEED_250 250000000
+struct adm5120_board {
+ char name[ADM5120_BOARD_NAMELEN];
+ unsigned long mach_type;
+ unsigned int iface_num; /* Number of Ethernet interfaces */
+ unsigned int has_usb; /* USB controller presence flag */
+ u32 flash0_size; /* Flash 0 size */
+};
-#define CPU_PACKAGE_PQFP 0
-#define CPU_PACKAGE_BGA 1
+extern struct adm5120_board adm5120_board;
+extern unsigned int adm5120_boot_loader;
#define BOOT_LOADER_UNKNOWN 0
#define BOOT_LOADER_CFE 1
#define BOOT_LOADER_UBOOT 2
#define BOOT_LOADER_MYLOADER 3
#define BOOT_LOADER_ROUTERBOOT 4
-#define BOOT_LOADER_LAST 4
+#define BOOT_LOADER_BOOTBASE 5
+#define BOOT_LOADER_LAST 5
+
+extern unsigned int adm5120_product_code;
+extern unsigned int adm5120_revision;
+extern unsigned int adm5120_nand_boot;
-#define BOARD_TYPE_UNKNOWN 0
-#define BOARD_TYPE_WP54G_WRT 1
-#define BOARD_TYPE_WP54G 2
-#define BOARD_TYPE_WP54AG 3
-#define BOARD_TYPE_WPP54G 4
-#define BOARD_TYPE_WPP54AG 5
-#define BOARD_TYPE_NP28G 6
-#define BOARD_TYPE_NP28GHS 7
-#define BOARD_TYPE_NP27G 8
-#define BOARD_TYPE_WP54Gv1C 9
-#define BOARD_TYPE_RB_111 10
-#define BOARD_TYPE_RB_112 11
-#define BOARD_TYPE_RB_133 12
-#define BOARD_TYPE_RB_133C 13
-#define BOARD_TYPE_RB_150 14
-#define BOARD_TYPE_RB_153 15
-#define BOART_TYPE_LAST 15
+extern unsigned long adm5120_speed;
+#define ADM5120_SPEED_175 175000000
+#define ADM5120_SPEED_200 200000000
+#define ADM5120_SPEED_225 225000000
+#define ADM5120_SPEED_250 250000000
+
+extern unsigned int adm5120_package;
+#define ADM5120_PACKAGE_PQFP 0
+#define ADM5120_PACKAGE_BGA 1
-extern struct adm5120_info adm5120_info;
extern void adm5120_info_init(void);
static inline int adm5120_has_pci(void)
{
- return (adm5120_info.cpu_package == CPU_PACKAGE_BGA);
+ return (adm5120_package == ADM5120_PACKAGE_BGA);
+}
+
+static inline int adm5120_has_gmii(void)
+{
+ return (adm5120_package == ADM5120_PACKAGE_BGA);
+}
+
+static inline char *adm5120_board_name(void)
+{
+ return adm5120_board.name;
}
#endif /* _ADM5120_INFO_H */
diff --git a/target/linux/adm5120-2.6/image/lzma-loader/Makefile b/target/linux/adm5120-2.6/image/lzma-loader/Makefile
index 8ce26882345..175a1845ce0 100644
--- a/target/linux/adm5120-2.6/image/lzma-loader/Makefile
+++ b/target/linux/adm5120-2.6/image/lzma-loader/Makefile
@@ -31,7 +31,7 @@ install:
ifneq ($(TARGET),)
install: compile
- $(CP) $(PKG_BUILD_DIR)/$(LOADER).gz $(PKG_BUILD_DIR)/$(LOADER).elf $(TARGET)/
+ $(CP) $(PKG_BUILD_DIR)/$(LOADER).gz $(PKG_BUILD_DIR)/$(LOADER).elf $(PKG_BUILD_DIR)/$(LOADER).bin $(TARGET)/
endif
clean:
diff --git a/target/linux/adm5120-2.6/patches/001-adm5120.patch b/target/linux/adm5120-2.6/patches/001-adm5120.patch
index b6919708381..925ef3c91c7 100644
--- a/target/linux/adm5120-2.6/patches/001-adm5120.patch
+++ b/target/linux/adm5120-2.6/patches/001-adm5120.patch
@@ -1,16 +1,17 @@
diff -urN linux-2.6.19.2/arch/mips/Kconfig linux-2.6.19.2.new/arch/mips/Kconfig
--- linux-2.6.19.2/arch/mips/Kconfig 2007-01-10 20:10:37.000000000 +0100
+++ linux-2.6.19.2.new/arch/mips/Kconfig 2007-01-23 14:49:38.000000000 +0100
-@@ -12,6 +12,18 @@
+@@ -12,6 +12,19 @@
prompt "System type"
default SGI_IP22
-
+
+config MIPS_ADM5120
+ bool "Support for ADM5120 SoC"
+ select SYS_HAS_CPU_MIPS32_R1
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
++ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_32BIT_KERNEL
+
+config PCI_ADM5120
@@ -25,7 +26,7 @@ diff -urN linux-2.6.19.2/arch/mips/Makefile linux-2.6.19.2.new/arch/mips/Makefil
+++ linux-2.6.19.2.new/arch/mips/Makefile 2007-01-23 14:49:39.000000000 +0100
@@ -165,6 +165,14 @@
load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000
-
+
#
+# ADMtek 5120
+#
@@ -49,16 +50,41 @@ diff -urN linux-2.6.19.2/arch/mips/pci/Makefile linux-2.6.19.2.new/arch/mips/pci
diff -urN linux-2.6.19.2/include/asm-mips/bootinfo.h linux-2.6.19.2.new/include/asm-mips/bootinfo.h
--- linux-2.6.19.2/include/asm-mips/bootinfo.h 2007-01-10 20:10:37.000000000 +0100
+++ linux-2.6.19.2.new/include/asm-mips/bootinfo.h 2007-01-23 14:49:40.000000000 +0100
-@@ -212,6 +212,12 @@
+@@ -212,6 +212,37 @@
#define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */
#define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */
-
+
+/*
-+ * Valid machtype for group ADMtek
++ * Valid machtype for group ADMtek ADM5120
+ */
-+#define MACH_GROUP_ADM_GW 23
-+#define MACH_ADM_GW_5120 0
++#define MACH_GROUP_ADM5120 23
++#define MACH_ADM5120_UNKNOWN 0 /* Unknown board */
++#define MACH_ADM5120_WP54G_WRT 1 /* Compex WP54G-WRT */
++#define MACH_ADM5120_WP54G 2 /* Compex WP54G */
++#define MACH_ADM5120_WP54AG 3 /* Compex WP54AG */
++#define MACH_ADM5120_WPP54G 4 /* Compex WPP54G */
++#define MACH_ADM5120_WPP54AG 5 /* Compex WPP54AG */
++#define MACH_ADM5120_NP28G 6 /* Compex NP28G */
++#define MACH_ADM5120_NP28GHS 7 /* Compex NP28G HotSpot */
++#define MACH_ADM5120_NP27G 8 /* Compex NP27G */
++#define MACH_ADM5120_WP54Gv1C 9 /* Compex WP54G version 1C */
++#define MACH_ADM5120_RB_111 10 /* Mikrotik RouterBOARD 111 */
++#define MACH_ADM5120_RB_112 11 /* Mikrotik RouterBOARD 112 */
++#define MACH_ADM5120_RB_133 12 /* Mikrotik RouterBOARD 133 */
++#define MACH_ADM5120_RB_133C 13 /* Mikrotik RouterBOARD 133c */
++#define MACH_ADM5120_RB_150 14 /* Mikrotik RouterBOARD 150 */
++#define MACH_ADM5120_RB_153 15 /* Mikrotik RouterBOARD 153 */
++#define MACH_ADM5120_HS100 16 /* ZyXEL HomeSafe 100/100W */
++#define MACH_ADM5120_P334 17 /* ZyXEL Prestige 334 */
++#define MACH_ADM5120_P334U 18 /* ZyXEL Prestige 334U */
++#define MACH_ADM5120_P334W 18 /* ZyXEL Prestige 334W */
++#define MACH_ADM5120_P334WH 19 /* ZyXEL Prestige 334WH */
++#define MACH_ADM5120_P334WHD 20 /* ZyXEL Prestige 334WHD */
++#define MACH_ADM5120_P334WT 21 /* ZyXEL Prestige 334WT */
++#define MACH_ADM5120_P335 22 /* ZyXEL Prestige 335/335WT */
++#define MACH_ADM5120_P335PLUS 23 /* ZyXEL Prestige 335Plus */
++#define MACH_ADM5120_P335U 24 /* ZyXEL Prestige 335U */
+
#define CL_SIZE COMMAND_LINE_SIZE
-
+
const char *get_system_type(void);
n2445'>2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270
## gMock Cookbook

<!-- GOOGLETEST_CM0012 DO NOT DELETE -->

You can find recipes for using gMock here. If you haven't yet, please read
[this](for_dummies.md) first to make sure you understand the basics.

**Note:** gMock lives in the `testing` name space. For readability, it is
recommended to write `using ::testing::Foo;` once in your file before using the
name `Foo` defined by gMock. We omit such `using` statements in this section for
brevity, but you should do it in your own code.

### Creating Mock Classes

Mock classes are defined as normal classes, using the `MOCK_METHOD` macro to
generate mocked methods. The macro gets 3 or 4 parameters:

```cpp
class MyMock {
 public:
  MOCK_METHOD(ReturnType, MethodName, (Args...));
  MOCK_METHOD(ReturnType, MethodName, (Args...), (Specs...));
};
```

The first 3 parameters are simply the method declaration, split into 3 parts.
The 4th parameter accepts a closed list of qualifiers, which affect the
generated method:

*   **`const`** - Makes the mocked method a `const` method. Required if
    overriding a `const` method.
*   **`override`** - Marks the method with `override`. Recommended if overriding
    a `virtual` method.
*   **`noexcept`** - Marks the method with `noexcept`. Required if overriding a
    `noexcept` method.
*   **`Calltype(...)`** - Sets the call type for the method (e.g. to
    `STDMETHODCALLTYPE`), useful in Windows.

#### Dealing with unprotected commas

Unprotected commas, i.e. commas which are not surrounded by parentheses, prevent
`MOCK_METHOD` from parsing its arguments correctly:

```cpp {.bad}
class MockFoo {
 public:
  MOCK_METHOD(std::pair<bool, int>, GetPair, ());  // Won't compile!
  MOCK_METHOD(bool, CheckMap, (std::map<int, double>, bool));  // Won't compile!
};
```

Solution 1 - wrap with parentheses:

```cpp {.good}
class MockFoo {
 public:
  MOCK_METHOD((std::pair<bool, int>), GetPair, ());
  MOCK_METHOD(bool, CheckMap, ((std::map<int, double>), bool));
};
```

Note that wrapping a return or argument type with parentheses is, in general,
invalid C++. `MOCK_METHOD` removes the parentheses.

Solution 2 - define an alias:

```cpp {.good}
class MockFoo {
 public:
  using BoolAndInt = std::pair<bool, int>;
  MOCK_METHOD(BoolAndInt, GetPair, ());
  using MapIntDouble = std::map<int, double>;
  MOCK_METHOD(bool, CheckMap, (MapIntDouble, bool));
};
```

#### Mocking Private or Protected Methods

You must always put a mock method definition (`MOCK_METHOD`) in a `public:`
section of the mock class, regardless of the method being mocked being `public`,
`protected`, or `private` in the base class. This allows `ON_CALL` and
`EXPECT_CALL` to reference the mock function from outside of the mock class.
(Yes, C++ allows a subclass to change the access level of a virtual function in
the base class.) Example:

```cpp
class Foo {
 public:
  ...
  virtual bool Transform(Gadget* g) = 0;

 protected:
  virtual void Resume();

 private:
  virtual int GetTimeOut();
};

class MockFoo : public Foo {
 public:
  ...
  MOCK_METHOD(bool, Transform, (Gadget* g), (override));

  // The following must be in the public section, even though the
  // methods are protected or private in the base class.
  MOCK_METHOD(void, Resume, (), (override));
  MOCK_METHOD(int, GetTimeOut, (), (override));
};
```

#### Mocking Overloaded Methods

You can mock overloaded functions as usual. No special attention is required:

```cpp
class Foo {
  ...

  // Must be virtual as we'll inherit from Foo.
  virtual ~Foo();

  // Overloaded on the types and/or numbers of arguments.
  virtual int Add(Element x);
  virtual int Add(int times, Element x);

  // Overloaded on the const-ness of this object.
  virtual Bar& GetBar();
  virtual const Bar& GetBar() const;
};

class MockFoo : public Foo {
  ...
  MOCK_METHOD(int, Add, (Element x), (override));
  MOCK_METHOD(int, Add, (int times, Element x), (override));

  MOCK_METHOD(Bar&, GetBar, (), (override));
  MOCK_METHOD(const Bar&, GetBar, (), (const, override));
};
```

**Note:** if you don't mock all versions of the overloaded method, the compiler
will give you a warning about some methods in the base class being hidden. To
fix that, use `using` to bring them in scope:

```cpp
class MockFoo : public Foo {
  ...
  using Foo::Add;
  MOCK_METHOD(int, Add, (Element x), (override));
  // We don't want to mock int Add(int times, Element x);
  ...
};
```

#### Mocking Class Templates

You can mock class templates just like any class.

```cpp
template <typename Elem>
class StackInterface {
  ...
  // Must be virtual as we'll inherit from StackInterface.
  virtual ~StackInterface();

  virtual int GetSize() const = 0;
  virtual void Push(const Elem& x) = 0;
};

template <typename Elem>
class MockStack : public StackInterface<Elem> {
  ...
  MOCK_METHOD(int, GetSize, (), (override));
  MOCK_METHOD(void, Push, (const Elem& x), (override));
};
```

#### Mocking Non-virtual Methods {#MockingNonVirtualMethods}

gMock can mock non-virtual functions to be used in Hi-perf dependency
injection.<!-- GOOGLETEST_CM0017 DO NOT DELETE -->

In this case, instead of sharing a common base class with the real class, your
mock class will be *unrelated* to the real class, but contain methods with the
same signatures. The syntax for mocking non-virtual methods is the *same* as
mocking virtual methods (just don't add `override`):

```cpp
// A simple packet stream class.  None of its members is virtual.
class ConcretePacketStream {
 public:
  void AppendPacket(Packet* new_packet);
  const Packet* GetPacket(size_t packet_number) const;
  size_t NumberOfPackets() const;
  ...
};

// A mock packet stream class.  It inherits from no other, but defines
// GetPacket() and NumberOfPackets().
class MockPacketStream {
 public:
  MOCK_METHOD(const Packet*, GetPacket, (size_t packet_number), (const));
  MOCK_METHOD(size_t, NumberOfPackets, (), (const));
  ...
};
```

Note that the mock class doesn't define `AppendPacket()`, unlike the real class.
That's fine as long as the test doesn't need to call it.

Next, you need a way to say that you want to use `ConcretePacketStream` in
production code, and use `MockPacketStream` in tests. Since the functions are
not virtual and the two classes are unrelated, you must specify your choice at
*compile time* (as opposed to run time).

One way to do it is to templatize your code that needs to use a packet stream.
More specifically, you will give your code a template type argument for the type
of the packet stream. In production, you will instantiate your template with
`ConcretePacketStream` as the type argument. In tests, you will instantiate the
same template with `MockPacketStream`. For example, you may write:

```cpp
template <class PacketStream>
void CreateConnection(PacketStream* stream) { ... }

template <class PacketStream>
class PacketReader {
 public:
  void ReadPackets(PacketStream* stream, size_t packet_num);
};
```

Then you can use `CreateConnection<ConcretePacketStream>()` and
`PacketReader<ConcretePacketStream>` in production code, and use
`CreateConnection<MockPacketStream>()` and `PacketReader<MockPacketStream>` in
tests.

```cpp
  MockPacketStream mock_stream;
  EXPECT_CALL(mock_stream, ...)...;
  .. set more expectations on mock_stream ...
  PacketReader<MockPacketStream> reader(&mock_stream);
  ... exercise reader ...
```

#### Mocking Free Functions

It's possible to use gMock to mock a free function (i.e. a C-style function or a
static method). You just need to rewrite your code to use an interface (abstract
class).

Instead of calling a free function (say, `OpenFile`) directly, introduce an
interface for it and have a concrete subclass that calls the free function:

```cpp
class FileInterface {
 public:
  ...
  virtual bool Open(const char* path, const char* mode) = 0;
};

class File : public FileInterface {
 public:
  ...
  virtual bool Open(const char* path, const char* mode) {
     return OpenFile(path, mode);
  }
};
```

Your code should talk to `FileInterface` to open a file. Now it's easy to mock
out the function.

This may seem like a lot of hassle, but in practice you often have multiple
related functions that you can put in the same interface, so the per-function
syntactic overhead will be much lower.

If you are concerned about the performance overhead incurred by virtual
functions, and profiling confirms your concern, you can combine this with the
recipe for [mocking non-virtual methods](#MockingNonVirtualMethods).

#### Old-Style `MOCK_METHODn` Macros

Before the generic `MOCK_METHOD` macro was introduced, mocks where created using
a family of macros collectively called `MOCK_METHODn`. These macros are still
supported, though migration to the new `MOCK_METHOD` is recommended.

The macros in the `MOCK_METHODn` family differ from `MOCK_METHOD`:

*   The general structure is `MOCK_METHODn(MethodName, ReturnType(Args))`,
    instead of `MOCK_METHOD(ReturnType, MethodName, (Args))`.
*   The number `n` must equal the number of arguments.
*   When mocking a const method, one must use `MOCK_CONST_METHODn`.
*   When mocking a class template, the macro name must be suffixed with `_T`.
*   In order to specify the call type, the macro name must be suffixed with
    `_WITH_CALLTYPE`, and the call type is the first macro argument.

Old macros and their new equivalents:

<a name="table99"></a>
<table border="1" cellspacing="0" cellpadding="1">
<tr> <th colspan=2> Simple </th></tr>
<tr> <td> Old </td> <td> `MOCK_METHOD1(Foo, bool(int))` </td> </tr>
<tr> <td> New </td> <td> `MOCK_METHOD(bool, Foo, (int))` </td> </tr>

<tr> <th colspan=2> Const Method </th></tr> <tr> <td> Old </td> <td>
`MOCK_CONST_METHOD1(Foo, bool(int))` </td> </tr> <tr> <td> New </td> <td>
`MOCK_METHOD(bool, Foo, (int), (const))` </td> </tr>

<tr> <th colspan=2> Method in a Class Template </th></tr> <tr> <td> Old </td>
<td> `MOCK_METHOD1_T(Foo, bool(int))` </td> </tr> <tr> <td> New </td> <td>
`MOCK_METHOD(bool, Foo, (int))` </td> </tr>

<tr> <th colspan=2> Const Method in a Class Template </th></tr> <tr> <td> Old
</td> <td> `MOCK_CONST_METHOD1_T(Foo, bool(int))` </td> </tr> <tr> <td> New
</td> <td> `MOCK_METHOD(bool, Foo, (int), (const))` </td> </tr>

<tr> <th colspan=2> Method with Call Type </th></tr> <tr> <td> Old </td> <td>
`MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))` </td> </tr> <tr>
<td> New </td> <td> `MOCK_METHOD(bool, Foo, (int),
(Calltype(STDMETHODCALLTYPE)))` </td> </tr>

<tr> <th colspan=2> Const Method with Call Type </th></tr> <tr> <td> Old</td>
<td> `MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))` </td>
</tr> <tr> <td> New </td> <td> `MOCK_METHOD(bool, Foo, (int), (const,
Calltype(STDMETHODCALLTYPE)))` </td> </tr>

<tr> <th colspan=2> Method with Call Type in a Class Template </th></tr> <tr>
<td> Old </td> <td> `MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo,
bool(int))` </td> </tr> <tr> <td> New </td> <td> `MOCK_METHOD(bool, Foo, (int),
(Calltype(STDMETHODCALLTYPE)))` </td> </tr>

<tr> <th colspan=2> Const Method with Call Type in a Class Template </th></tr>
<tr> <td> Old </td> <td> `MOCK_CONST_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE,
Foo, bool(int))` </td> </tr> <tr> <td> New </td> <td> `MOCK_METHOD(bool, Foo,
(int), (const, Calltype(STDMETHODCALLTYPE)))` </td> </tr>

</table>

#### The Nice, the Strict, and the Naggy {#NiceStrictNaggy}

If a mock method has no `EXPECT_CALL` spec but is called, we say that it's an
"uninteresting call", and the default action (which can be specified using
`ON_CALL()`) of the method will be taken. Currently, an uninteresting call will
also by default cause gMock to print a warning. (In the future, we might remove
this warning by default.)

However, sometimes you may want to ignore these uninteresting calls, and
sometimes you may want to treat them as errors. gMock lets you make the decision
on a per-mock-object basis.

Suppose your test uses a mock class `MockFoo`:

```cpp
TEST(...) {
  MockFoo mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}
```

If a method of `mock_foo` other than `DoThis()` is called, you will get a
warning. However, if you rewrite your test to use `NiceMock<MockFoo>` instead,
you can suppress the warning:

```cpp
using ::testing::NiceMock;

TEST(...) {
  NiceMock<MockFoo> mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}
```

`NiceMock<MockFoo>` is a subclass of `MockFoo`, so it can be used wherever
`MockFoo` is accepted.

It also works if `MockFoo`'s constructor takes some arguments, as
`NiceMock<MockFoo>` "inherits" `MockFoo`'s constructors:

```cpp
using ::testing::NiceMock;

TEST(...) {
  NiceMock<MockFoo> mock_foo(5, "hi");  // Calls MockFoo(5, "hi").
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}
```

The usage of `StrictMock` is similar, except that it makes all uninteresting
calls failures:

```cpp
using ::testing::StrictMock;

TEST(...) {
  StrictMock<MockFoo> mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...

  // The test will fail if a method of mock_foo other than DoThis()
  // is called.
}
```

NOTE: `NiceMock` and `StrictMock` only affects *uninteresting* calls (calls of
*methods* with no expectations); they do not affect *unexpected* calls (calls of
methods with expectations, but they don't match). See
[Understanding Uninteresting vs Unexpected Calls](#uninteresting-vs-unexpected).

There are some caveats though (I dislike them just as much as the next guy, but
sadly they are side effects of C++'s limitations):

1.  `NiceMock<MockFoo>` and `StrictMock<MockFoo>` only work for mock methods
    defined using the `MOCK_METHOD` macro **directly** in the `MockFoo` class.
    If a mock method is defined in a **base class** of `MockFoo`, the "nice" or
    "strict" modifier may not affect it, depending on the compiler. In
    particular, nesting `NiceMock` and `StrictMock` (e.g.
    `NiceMock<StrictMock<MockFoo> >`) is **not** supported.
2.  `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the
    destructor of `MockFoo` is not virtual. We would like to fix this, but it
    requires cleaning up existing tests. http://b/28934720 tracks the issue.
3.  During the constructor or destructor of `MockFoo`, the mock object is *not*
    nice or strict. This may cause surprises if the constructor or destructor
    calls a mock method on `this` object. (This behavior, however, is consistent
    with C++'s general rule: if a constructor or destructor calls a virtual
    method of `this` object, that method is treated as non-virtual. In other
    words, to the base class's constructor or destructor, `this` object behaves
    like an instance of the base class, not the derived class. This rule is
    required for safety. Otherwise a base constructor may use members of a
    derived class before they are initialized, or a base destructor may use
    members of a derived class after they have been destroyed.)

Finally, you should be **very cautious** about when to use naggy or strict
mocks, as they tend to make tests more brittle and harder to maintain. When you
refactor your code without changing its externally visible behavior, ideally you
shouldn't need to update any tests. If your code interacts with a naggy mock,
however, you may start to get spammed with warnings as the result of your
change. Worse, if your code interacts with a strict mock, your tests may start
to fail and you'll be forced to fix them. Our general recommendation is to use
nice mocks (not yet the default) most of the time, use naggy mocks (the current
default) when developing or debugging tests, and use strict mocks only as the
last resort.

#### Simplifying the Interface without Breaking Existing Code {#SimplerInterfaces}

Sometimes a method has a long list of arguments that is mostly uninteresting.
For example:

```cpp
class LogSink {
 public:
  ...
  virtual void send(LogSeverity severity, const char* full_filename,
                    const char* base_filename, int line,
                    const struct tm* tm_time,
                    const char* message, size_t message_len) = 0;
};
```

This method's argument list is lengthy and hard to work with (the `message`
argument is not even 0-terminated). If we mock it as is, using the mock will be
awkward. If, however, we try to simplify this interface, we'll need to fix all
clients depending on it, which is often infeasible.

The trick is to redispatch the method in the mock class:

```cpp
class ScopedMockLog : public LogSink {
 public:
  ...
  virtual void send(LogSeverity severity, const char* full_filename,
                    const char* base_filename, int line, const tm* tm_time,
                    const char* message, size_t message_len) {
    // We are only interested in the log severity, full file name, and
    // log message.
    Log(severity, full_filename, std::string(message, message_len));
  }

  // Implements the mock method:
  //
  //   void Log(LogSeverity severity,
  //            const string& file_path,
  //            const string& message);
  MOCK_METHOD(void, Log,
              (LogSeverity severity, const string& file_path,
               const string& message));
};
```

By defining a new mock method with a trimmed argument list, we make the mock
class more user-friendly.

This technique may also be applied to make overloaded methods more amenable to
mocking. For example, when overloads have been used to implement default
arguments:

```cpp
class MockTurtleFactory : public TurtleFactory {
 public:
  Turtle* MakeTurtle(int length, int weight) override { ... }
  Turtle* MakeTurtle(int length, int weight, int speed) override { ... }

  // the above methods delegate to this one:
  MOCK_METHOD(Turtle*, DoMakeTurtle, ());
};
```

This allows tests that don't care which overload was invoked to avoid specifying
argument matchers:

```cpp
ON_CALL(factory, DoMakeTurtle)
    .WillByDefault(MakeMockTurtle());
```

#### Alternative to Mocking Concrete Classes

Often you may find yourself using classes that don't implement interfaces. In
order to test your code that uses such a class (let's call it `Concrete`), you
may be tempted to make the methods of `Concrete` virtual and then mock it.

Try not to do that.

Making a non-virtual function virtual is a big decision. It creates an extension
point where subclasses can tweak your class' behavior. This weakens your control
on the class because now it's harder to maintain the class invariants. You
should make a function virtual only when there is a valid reason for a subclass
to override it.

Mocking concrete classes directly is problematic as it creates a tight coupling
between the class and the tests - any small change in the class may invalidate
your tests and make test maintenance a pain.

To avoid such problems, many programmers have been practicing "coding to
interfaces": instead of talking to the `Concrete` class, your code would define
an interface and talk to it. Then you implement that interface as an adaptor on
top of `Concrete`. In tests, you can easily mock that interface to observe how
your code is doing.

This technique incurs some overhead:

*   You pay the cost of virtual function calls (usually not a problem).
*   There is more abstraction for the programmers to learn.

However, it can also bring significant benefits in addition to better
testability:

*   `Concrete`'s API may not fit your problem domain very well, as you may not
    be the only client it tries to serve. By designing your own interface, you
    have a chance to tailor it to your need - you may add higher-level
    functionalities, rename stuff, etc instead of just trimming the class. This
    allows you to write your code (user of the interface) in a more natural way,
    which means it will be more readable, more maintainable, and you'll be more
    productive.
*   If `Concrete`'s implementation ever has to change, you don't have to rewrite
    everywhere it is used. Instead, you can absorb the change in your
    implementation of the interface, and your other code and tests will be
    insulated from this change.

Some people worry that if everyone is practicing this technique, they will end
up writing lots of redundant code. This concern is totally understandable.
However, there are two reasons why it may not be the case:

*   Different projects may need to use `Concrete` in different ways, so the best
    interfaces for them will be different. Therefore, each of them will have its
    own domain-specific interface on top of `Concrete`, and they will not be the
    same code.
*   If enough projects want to use the same interface, they can always share it,
    just like they have been sharing `Concrete`. You can check in the interface
    and the adaptor somewhere near `Concrete` (perhaps in a `contrib`
    sub-directory) and let many projects use it.

You need to weigh the pros and cons carefully for your particular problem, but
I'd like to assure you that the Java community has been practicing this for a
long time and it's a proven effective technique applicable in a wide variety of
situations. :-)

#### Delegating Calls to a Fake {#DelegatingToFake}

Some times you have a non-trivial fake implementation of an interface. For
example:

```cpp
class Foo {
 public:
  virtual ~Foo() {}
  virtual char DoThis(int n) = 0;
  virtual void DoThat(const char* s, int* p) = 0;
};

class FakeFoo : public Foo {
 public:
  char DoThis(int n) override {
    return (n > 0) ? '+' :
           (n < 0) ? '-' : '0';
  }

  void DoThat(const char* s, int* p) override {
    *p = strlen(s);
  }
};
```

Now you want to mock this interface such that you can set expectations on it.
However, you also want to use `FakeFoo` for the default behavior, as duplicating
it in the mock object is, well, a lot of work.

When you define the mock class using gMock, you can have it delegate its default
action to a fake class you already have, using this pattern:

```cpp
class MockFoo : public Foo {
 public:
  // Normal mock method definitions using gMock.
  MOCK_METHOD(char, DoThis, (int n), (override));
  MOCK_METHOD(void, DoThat, (const char* s, int* p), (override));

  // Delegates the default actions of the methods to a FakeFoo object.
  // This must be called *before* the custom ON_CALL() statements.
  void DelegateToFake() {
    ON_CALL(*this, DoThis).WillByDefault([this](int n) {
      return fake_.DoThis(n);
    });
    ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) {
      fake_.DoThat(s, p);
    });
  }

 private:
  FakeFoo fake_;  // Keeps an instance of the fake in the mock.
};
```

With that, you can use `MockFoo` in your tests as usual. Just remember that if
you don't explicitly set an action in an `ON_CALL()` or `EXPECT_CALL()`, the
fake will be called upon to do it.:

```cpp
using ::testing::_;

TEST(AbcTest, Xyz) {
  MockFoo foo;

  foo.DelegateToFake();  // Enables the fake for delegation.

  // Put your ON_CALL(foo, ...)s here, if any.

  // No action specified, meaning to use the default action.
  EXPECT_CALL(foo, DoThis(5));
  EXPECT_CALL(foo, DoThat(_, _));

  int n = 0;
  EXPECT_EQ('+', foo.DoThis(5));  // FakeFoo::DoThis() is invoked.
  foo.DoThat("Hi", &n);  // FakeFoo::DoThat() is invoked.
  EXPECT_EQ(2, n);
}
```

**Some tips:**

*   If you want, you can still override the default action by providing your own
    `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`.
*   In `DelegateToFake()`, you only need to delegate the methods whose fake
    implementation you intend to use.

*   The general technique discussed here works for overloaded methods, but
    you'll need to tell the compiler which version you mean. To disambiguate a
    mock function (the one you specify inside the parentheses of `ON_CALL()`),
    use [this technique](#SelectOverload); to disambiguate a fake function (the
    one you place inside `Invoke()`), use a `static_cast` to specify the
    function's type. For instance, if class `Foo` has methods `char DoThis(int
    n)` and `bool DoThis(double x) const`, and you want to invoke the latter,
    you need to write `Invoke(&fake_, static_cast<bool (FakeFoo::*)(double)
    const>(&FakeFoo::DoThis))` instead of `Invoke(&fake_, &FakeFoo::DoThis)`
    (The strange-looking thing inside the angled brackets of `static_cast` is
    the type of a function pointer to the second `DoThis()` method.).

*   Having to mix a mock and a fake is often a sign of something gone wrong.
    Perhaps you haven't got used to the interaction-based way of testing yet. Or
    perhaps your interface is taking on too many roles and should be split up.
    Therefore, **don't abuse this**. We would only recommend to do it as an
    intermediate step when you are refactoring your code.

Regarding the tip on mixing a mock and a fake, here's an example on why it may
be a bad sign: Suppose you have a class `System` for low-level system
operations. In particular, it does file and I/O operations. And suppose you want
to test how your code uses `System` to do I/O, and you just want the file
operations to work normally. If you mock out the entire `System` class, you'll
have to provide a fake implementation for the file operation part, which
suggests that `System` is taking on too many roles.

Instead, you can define a `FileOps` interface and an `IOOps` interface and split
`System`'s functionalities into the two. Then you can mock `IOOps` without
mocking `FileOps`.

#### Delegating Calls to a Real Object

When using testing doubles (mocks, fakes, stubs, and etc), sometimes their
behaviors will differ from those of the real objects. This difference could be
either intentional (as in simulating an error such that you can test the error
handling code) or unintentional. If your mocks have different behaviors than the
real objects by mistake, you could end up with code that passes the tests but
fails in production.

You can use the *delegating-to-real* technique to ensure that your mock has the
same behavior as the real object while retaining the ability to validate calls.
This technique is very similar to the [delegating-to-fake](#DelegatingToFake)
technique, the difference being that we use a real object instead of a fake.
Here's an example:

```cpp
using ::testing::AtLeast;

class MockFoo : public Foo {
 public:
  MockFoo() {
    // By default, all calls are delegated to the real object.
    ON_CALL(*this, DoThis).WillByDefault([this](int n) {
      return real_.DoThis(n);
    });
    ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) {
      real_.DoThat(s, p);
    });
    ...
  }
  MOCK_METHOD(char, DoThis, ...);
  MOCK_METHOD(void, DoThat, ...);
  ...
 private:
  Foo real_;
};

...
  MockFoo mock;
  EXPECT_CALL(mock, DoThis())
      .Times(3);
  EXPECT_CALL(mock, DoThat("Hi"))
      .Times(AtLeast(1));
  ... use mock in test ...
```

With this, gMock will verify that your code made the right calls (with the right
arguments, in the right order, called the right number of times, etc), and a
real object will answer the calls (so the behavior will be the same as in
production). This gives you the best of both worlds.

#### Delegating Calls to a Parent Class

Ideally, you should code to interfaces, whose methods are all pure virtual. In
reality, sometimes you do need to mock a virtual method that is not pure (i.e,
it already has an implementation). For example:

```cpp
class Foo {
 public:
  virtual ~Foo();

  virtual void Pure(int n) = 0;
  virtual int Concrete(const char* str) { ... }
};

class MockFoo : public Foo {
 public:
  // Mocking a pure method.
  MOCK_METHOD(void, Pure, (int n), (override));
  // Mocking a concrete method.  Foo::Concrete() is shadowed.
  MOCK_METHOD(int, Concrete, (const char* str), (override));
};
```

Sometimes you may want to call `Foo::Concrete()` instead of
`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub action, or
perhaps your test doesn't need to mock `Concrete()` at all (but it would be
oh-so painful to have to define a new mock class whenever you don't need to mock
one of its methods).

The trick is to leave a back door in your mock class for accessing the real
methods in the base class:

```cpp
class MockFoo : public Foo {
 public:
  // Mocking a pure method.
  MOCK_METHOD(void, Pure, (int n), (override));
  // Mocking a concrete method.  Foo::Concrete() is shadowed.
  MOCK_METHOD(int, Concrete, (const char* str), (override));

  // Use this to call Concrete() defined in Foo.
  int FooConcrete(const char* str) { return Foo::Concrete(str); }
};
```

Now, you can call `Foo::Concrete()` inside an action by:

```cpp
...
  EXPECT_CALL(foo, Concrete).WillOnce([&foo](const char* str) {
    return foo.FooConcrete(str);
  });
```

or tell the mock object that you don't want to mock `Concrete()`:

```cpp
...
  ON_CALL(foo, Concrete).WillByDefault([&foo](const char* str) {
    return foo.FooConcrete(str);
  });
```

(Why don't we just write `{ return foo.Concrete(str); }`? If you do that,
`MockFoo::Concrete()` will be called (and cause an infinite recursion) since
`Foo::Concrete()` is virtual. That's just how C++ works.)

### Using Matchers

#### Matching Argument Values Exactly

You can specify exactly which arguments a mock method is expecting:

```cpp
using ::testing::Return;
...
  EXPECT_CALL(foo, DoThis(5))
      .WillOnce(Return('a'));
  EXPECT_CALL(foo, DoThat("Hello", bar));
```

#### Using Simple Matchers

You can use matchers to match arguments that have a certain property:

```cpp
using ::testing::NotNull;
using ::testing::Return;
...
  EXPECT_CALL(foo, DoThis(Ge(5)))  // The argument must be >= 5.
      .WillOnce(Return('a'));
  EXPECT_CALL(foo, DoThat("Hello", NotNull()));
      // The second argument must not be NULL.
```

A frequently used matcher is `_`, which matches anything:

```cpp
  EXPECT_CALL(foo, DoThat(_, NotNull()));
```
<!-- GOOGLETEST_CM0022 DO NOT DELETE -->

#### Combining Matchers {#CombiningMatchers}

You can build complex matchers from existing ones using `AllOf()`,
`AllOfArray()`, `AnyOf()`, `AnyOfArray()` and `Not()`:

```cpp
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::Ne;
using ::testing::Not;
...
  // The argument must be > 5 and != 10.
  EXPECT_CALL(foo, DoThis(AllOf(Gt(5),
                                Ne(10))));

  // The first argument must not contain sub-string "blah".
  EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")),
                          NULL));
```

#### Casting Matchers {#SafeMatcherCast}

gMock matchers are statically typed, meaning that the compiler can catch your
mistake if you use a matcher of the wrong type (for example, if you use `Eq(5)`
to match a `string` argument). Good for you!

Sometimes, however, you know what you're doing and want the compiler to give you
some slack. One example is that you have a matcher for `long` and the argument
you want to match is `int`. While the two types aren't exactly the same, there
is nothing really wrong with using a `Matcher<long>` to match an `int` - after
all, we can first convert the `int` argument to a `long` losslessly before
giving it to the matcher.

To support this need, gMock gives you the `SafeMatcherCast<T>(m)` function. It
casts a matcher `m` to type `Matcher<T>`. To ensure safety, gMock checks that
(let `U` be the type `m` accepts :

1.  Type `T` can be *implicitly* cast to type `U`;
2.  When both `T` and `U` are built-in arithmetic types (`bool`, integers, and
    floating-point numbers), the conversion from `T` to `U` is not lossy (in
    other words, any value representable by `T` can also be represented by `U`);
    and
3.  When `U` is a reference, `T` must also be a reference (as the underlying
    matcher may be interested in the address of the `U` value).

The code won't compile if any of these conditions isn't met.

Here's one example:

```cpp
using ::testing::SafeMatcherCast;

// A base class and a child class.
class Base { ... };
class Derived : public Base { ... };

class MockFoo : public Foo {
 public:
  MOCK_METHOD(void, DoThis, (Derived* derived), (override));
};

...
  MockFoo foo;
  // m is a Matcher<Base*> we got from somewhere.
  EXPECT_CALL(foo, DoThis(SafeMatcherCast<Derived*>(m)));
```

If you find `SafeMatcherCast<T>(m)` too limiting, you can use a similar function
`MatcherCast<T>(m)`. The difference is that `MatcherCast` works as long as you
can `static_cast` type `T` to type `U`.

`MatcherCast` essentially lets you bypass C++'s type system (`static_cast` isn't
always safe as it could throw away information, for example), so be careful not
to misuse/abuse it.

#### Selecting Between Overloaded Functions {#SelectOverload}

If you expect an overloaded function to be called, the compiler may need some
help on which overloaded version it is.

To disambiguate functions overloaded on the const-ness of this object, use the
`Const()` argument wrapper.

```cpp
using ::testing::ReturnRef;

class MockFoo : public Foo {
  ...
  MOCK_METHOD(Bar&, GetBar, (), (override));
  MOCK_METHOD(const Bar&, GetBar, (), (const, override));
};

...
  MockFoo foo;
  Bar bar1, bar2;
  EXPECT_CALL(foo, GetBar())         // The non-const GetBar().
      .WillOnce(ReturnRef(bar1));
  EXPECT_CALL(Const(foo), GetBar())  // The const GetBar().
      .WillOnce(ReturnRef(bar2));
```

(`Const()` is defined by gMock and returns a `const` reference to its argument.)

To disambiguate overloaded functions with the same number of arguments but
different argument types, you may need to specify the exact type of a matcher,
either by wrapping your matcher in `Matcher<type>()`, or using a matcher whose
type is fixed (`TypedEq<type>`, `An<type>()`, etc):

```cpp
using ::testing::An;
using ::testing::Matcher;
using ::testing::TypedEq;

class MockPrinter : public Printer {
 public:
  MOCK_METHOD(void, Print, (int n), (override));
  MOCK_METHOD(void, Print, (char c), (override));
};

TEST(PrinterTest, Print) {
  MockPrinter printer;

  EXPECT_CALL(printer, Print(An<int>()));            // void Print(int);
  EXPECT_CALL(printer, Print(Matcher<int>(Lt(5))));  // void Print(int);
  EXPECT_CALL(printer, Print(TypedEq<char>('a')));   // void Print(char);

  printer.Print(3);
  printer.Print(6);
  printer.Print('a');
}
```

#### Performing Different Actions Based on the Arguments

When a mock method is called, the *last* matching expectation that's still
active will be selected (think "newer overrides older"). So, you can make a
method do different things depending on its argument values like this:

```cpp
using ::testing::_;
using ::testing::Lt;
using ::testing::Return;
...
  // The default case.
  EXPECT_CALL(foo, DoThis(_))
      .WillRepeatedly(Return('b'));
  // The more specific case.
  EXPECT_CALL(foo, DoThis(Lt(5)))
      .WillRepeatedly(Return('a'));
```

Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will be
returned; otherwise `'b'` will be returned.

#### Matching Multiple Arguments as a Whole

Sometimes it's not enough to match the arguments individually. For example, we
may want to say that the first argument must be less than the second argument.
The `With()` clause allows us to match all arguments of a mock function as a
whole. For example,

```cpp
using ::testing::_;
using ::testing::Ne;
using ::testing::Lt;
...
  EXPECT_CALL(foo, InRange(Ne(0), _))
      .With(Lt());
```

says that the first argument of `InRange()` must not be 0, and must be less than
the second argument.

The expression inside `With()` must be a matcher of type
`Matcher< ::std::tuple<A1, ..., An> >`, where `A1`, ..., `An` are the types of
the function arguments.

You can also write `AllArgs(m)` instead of `m` inside `.With()`. The two forms
are equivalent, but `.With(AllArgs(Lt()))` is more readable than `.With(Lt())`.

You can use `Args<k1, ..., kn>(m)` to match the `n` selected arguments (as a
tuple) against `m`. For example,

```cpp
using ::testing::_;
using ::testing::AllOf;
using ::testing::Args;
using ::testing::Lt;
...
  EXPECT_CALL(foo, Blah)
      .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt())));
```

says that `Blah` will be called with arguments `x`, `y`, and `z` where `x < y <
z`. Note that in this example, it wasn't necessary specify the positional
matchers.

As a convenience and example, gMock provides some matchers for 2-tuples,
including the `Lt()` matcher above. See [here](#MultiArgMatchers) for the
complete list.

Note that if you want to pass the arguments to a predicate of your own (e.g.
`.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be written to
take a `::std::tuple` as its argument; gMock will pass the `n` selected
arguments as *one* single tuple to the predicate.

#### Using Matchers as Predicates

Have you noticed that a matcher is just a fancy predicate that also knows how to
describe itself? Many existing algorithms take predicates as arguments (e.g.
those defined in STL's `<algorithm>` header), and it would be a shame if gMock
matchers were not allowed to participate.

Luckily, you can use a matcher where a unary predicate functor is expected by
wrapping it inside the `Matches()` function. For example,

```cpp
#include <algorithm>
#include <vector>

using ::testing::Matches;
using ::testing::Ge;

vector<int> v;
...
// How many elements in v are >= 10?
const int count = count_if(v.begin(), v.end(), Matches(Ge(10)));
```

Since you can build complex matchers from simpler ones easily using gMock, this
gives you a way to conveniently construct composite predicates (doing the same
using STL's `<functional>` header is just painful). For example, here's a
predicate that's satisfied by any number that is >= 0, <= 100, and != 50:

```cpp
using testing::AllOf;
using testing::Ge;
using testing::Le;
using testing::Matches;
using testing::Ne;
...
Matches(AllOf(Ge(0), Le(100), Ne(50)))
```

#### Using Matchers in googletest Assertions

Since matchers are basically predicates that also know how to describe
themselves, there is a way to take advantage of them in googletest assertions.
It's called `ASSERT_THAT` and `EXPECT_THAT`:

```cpp
  ASSERT_THAT(value, matcher);  // Asserts that value matches matcher.
  EXPECT_THAT(value, matcher);  // The non-fatal version.
```

For example, in a googletest test you can write:

```cpp
#include "gmock/gmock.h"

using ::testing::AllOf;
using ::testing::Ge;
using ::testing::Le;
using ::testing::MatchesRegex;
using ::testing::StartsWith;

...
  EXPECT_THAT(Foo(), StartsWith("Hello"));
  EXPECT_THAT(Bar(), MatchesRegex("Line \\d+"));
  ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10)));
```

which (as you can probably guess) executes `Foo()`, `Bar()`, and `Baz()`, and
verifies that:

*   `Foo()` returns a string that starts with `"Hello"`.
*   `Bar()` returns a string that matches regular expression `"Line \\d+"`.
*   `Baz()` returns a number in the range [5, 10].

The nice thing about these macros is that *they read like English*. They
generate informative messages too. For example, if the first `EXPECT_THAT()`
above fails, the message will be something like:

```cpp
Value of: Foo()
  Actual: "Hi, world!"
Expected: starts with "Hello"
```

**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was borrowed from Joe Walnes'
Hamcrest project, which adds `assertThat()` to JUnit.

#### Using Predicates as Matchers

gMock provides a [built-in set](#MatcherList) of matchers. In case you find them
lacking, you can use an arbitrary unary predicate function or functor as a
matcher - as long as the predicate accepts a value of the type you want. You do
this by wrapping the predicate inside the `Truly()` function, for example:

```cpp
using ::testing::Truly;

int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; }
...
  // Bar() must be called with an even number.
  EXPECT_CALL(foo, Bar(Truly(IsEven)));
```

Note that the predicate function / functor doesn't have to return `bool`. It
works as long as the return value can be used as the condition in in statement
`if (condition) ...`.

<!-- GOOGLETEST_CM0023 DO NOT DELETE -->

#### Matching Arguments that Are Not Copyable

When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, gMock saves away a copy of
`bar`. When `Foo()` is called later, gMock compares the argument to `Foo()` with
the saved copy of `bar`. This way, you don't need to worry about `bar` being
modified or destroyed after the `EXPECT_CALL()` is executed. The same is true
when you use matchers like `Eq(bar)`, `Le(bar)`, and so on.

But what if `bar` cannot be copied (i.e. has no copy constructor)? You could
define your own matcher function or callback and use it with `Truly()`, as the
previous couple of recipes have shown. Or, you may be able to get away from it
if you can guarantee that `bar` won't be changed after the `EXPECT_CALL()` is
executed. Just tell gMock that it should save a reference to `bar`, instead of a
copy of it. Here's how:

```cpp
using ::testing::ByRef;
using ::testing::Eq;
using ::testing::Lt;
...
  // Expects that Foo()'s argument == bar.
  EXPECT_CALL(mock_obj, Foo(Eq(ByRef(bar))));

  // Expects that Foo()'s argument < bar.
  EXPECT_CALL(mock_obj, Foo(Lt(ByRef(bar))));
```

Remember: if you do this, don't change `bar` after the `EXPECT_CALL()`, or the
result is undefined.

#### Validating a Member of an Object

Often a mock function takes a reference to object as an argument. When matching
the argument, you may not want to compare the entire object against a fixed
object, as that may be over-specification. Instead, you may need to validate a
certain member variable or the result of a certain getter method of the object.
You can do this with `Field()` and `Property()`. More specifically,

```cpp
Field(&Foo::bar, m)
```

is a matcher that matches a `Foo` object whose `bar` member variable satisfies
matcher `m`.

```cpp
Property(&Foo::baz, m)
```

is a matcher that matches a `Foo` object whose `baz()` method returns a value
that satisfies matcher `m`.

For example:

<!-- mdformat off(github rendering does not support multiline tables) -->
| Expression                   | Description                              |
| :--------------------------- | :--------------------------------------- |
| `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`.       |
| `Property(&Foo::name,  StartsWith("John "))` | Matches `x` where `x.name()` starts with  `"John "`. |
<!-- mdformat on -->

Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no argument
and be declared as `const`.

BTW, `Field()` and `Property()` can also match plain pointers to objects. For
instance,

```cpp
using ::testing::Field;
using ::testing::Ge;
...
Field(&Foo::number, Ge(3))
```

matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, the match
will always fail regardless of the inner matcher.

What if you want to validate more than one members at the same time? Remember
that there are [`AllOf()` and `AllOfArray()`](#CombiningMatchers).

Finally `Field()` and `Property()` provide overloads that take the field or
property names as the first argument to include it in the error message. This
can be useful when creating combined matchers.

```cpp
using ::testing::AllOf;
using ::testing::Field;
using ::testing::Matcher;
using ::testing::SafeMatcherCast;

Matcher<Foo> IsFoo(const Foo& foo) {
  return AllOf(Field("some_field", &Foo::some_field, foo.some_field),
               Field("other_field", &Foo::other_field, foo.other_field),
               Field("last_field", &Foo::last_field, foo.last_field));
}
```

#### Validating the Value Pointed to by a Pointer Argument

C++ functions often take pointers as arguments. You can use matchers like
`IsNull()`, `NotNull()`, and other comparison matchers to match a pointer, but
what if you want to make sure the value *pointed to* by the pointer, instead of
the pointer itself, has a certain property? Well, you can use the `Pointee(m)`
matcher.

`Pointee(m)` matches a pointer if and only if `m` matches the value the pointer
points to. For example:

```cpp
using ::testing::Ge;
using ::testing::Pointee;
...
  EXPECT_CALL(foo, Bar(Pointee(Ge(3))));
```

expects `foo.Bar()` to be called with a pointer that points to a value greater
than or equal to 3.

One nice thing about `Pointee()` is that it treats a `NULL` pointer as a match
failure, so you can write `Pointee(m)` instead of

```cpp
using ::testing::AllOf;
using ::testing::NotNull;
using ::testing::Pointee;
...
  AllOf(NotNull(), Pointee(m))
```

without worrying that a `NULL` pointer will crash your test.

Also, did we tell you that `Pointee()` works with both raw pointers **and**
smart pointers (`std::unique_ptr`, `std::shared_ptr`, etc)?

What if you have a pointer to pointer? You guessed it - you can use nested
`Pointee()` to probe deeper inside the value. For example,
`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points
to a number less than 3 (what a mouthful...).

#### Testing a Certain Property of an Object

Sometimes you want to specify that an object argument has a certain property,
but there is no existing matcher that does this. If you want good error
messages, you should [define a matcher](#NewMatchers). If you want to do it
quick and dirty, you could get away with writing an ordinary function.

Let's say you have a mock function that takes an object of type `Foo`, which has
an `int bar()` method and an `int baz()` method, and you want to constrain that
the argument's `bar()` value plus its `baz()` value is a given number. Here's
how you can define a matcher to do it:

```cpp
using ::testing::Matcher;
using ::testing::MatcherInterface;
using ::testing::MatchResultListener;

class BarPlusBazEqMatcher : public MatcherInterface<const Foo&> {
 public:
  explicit BarPlusBazEqMatcher(int expected_sum)
      : expected_sum_(expected_sum) {}

  bool MatchAndExplain(const Foo& foo,
                       MatchResultListener* /* listener */) const override {
    return (foo.bar() + foo.baz()) == expected_sum_;
  }

  void DescribeTo(::std::ostream* os) const override {
    *os << "bar() + baz() equals " << expected_sum_;
  }

  void DescribeNegationTo(::std::ostream* os) const override {
    *os << "bar() + baz() does not equal " << expected_sum_;
  }
 private:
  const int expected_sum_;
};

Matcher<const Foo&> BarPlusBazEq(int expected_sum) {
  return MakeMatcher(new BarPlusBazEqMatcher(expected_sum));
}

...
  EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...;
```

#### Matching Containers

Sometimes an STL container (e.g. list, vector, map, ...) is passed to a mock
function and you may want to validate it. Since most STL containers support the
`==` operator, you can write `Eq(expected_container)` or simply
`expected_container` to match a container exactly.

Sometimes, though, you may want to be more flexible (for example, the first
element must be an exact match, but the second element can be any positive
number, and so on). Also, containers used in tests often have a small number of
elements, and having to define the expected container out-of-line is a bit of a
hassle.

You can use the `ElementsAre()` or `UnorderedElementsAre()` matcher in such
cases:

```cpp
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Gt;
...
  MOCK_METHOD(void, Foo, (const vector<int>& numbers), (override));
...
  EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5)));
```

The above matcher says that the container must have 4 elements, which must be 1,
greater than 0, anything, and 5 respectively.

If you instead write:

```cpp
using ::testing::_;
using ::testing::Gt;
using ::testing::UnorderedElementsAre;
...
  MOCK_METHOD(void, Foo, (const vector<int>& numbers), (override));
...
  EXPECT_CALL(mock, Foo(UnorderedElementsAre(1, Gt(0), _, 5)));
```

It means that the container must have 4 elements, which (under some permutation)
must be 1, greater than 0, anything, and 5 respectively.

As an alternative you can place the arguments in a C-style array and use
`ElementsAreArray()` or `UnorderedElementsAreArray()` instead:

```cpp
using ::testing::ElementsAreArray;
...
  // ElementsAreArray accepts an array of element values.
  const int expected_vector1[] = {1, 5, 2, 4, ...};
  EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1)));

  // Or, an array of element matchers.
  Matcher<int> expected_vector2[] = {1, Gt(2), _, 3, ...};
  EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2)));
```

In case the array needs to be dynamically created (and therefore the array size
cannot be inferred by the compiler), you can give `ElementsAreArray()` an
additional argument to specify the array size:

```cpp
using ::testing::ElementsAreArray;
...
  int* const expected_vector3 = new int[count];
  ... fill expected_vector3 with values ...
  EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count)));
```

Use `Pair` when comparing maps or other associative containers.

```cpp
using testing::ElementsAre;
using testing::Pair;
...
  std::map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
  EXPECT_THAT(m, ElementsAre(Pair("a", 1), Pair("b", 2), Pair("c", 3)));
```

**Tips:**

*   `ElementsAre*()` can be used to match *any* container that implements the
    STL iterator pattern (i.e. it has a `const_iterator` type and supports
    `begin()/end()`), not just the ones defined in STL. It will even work with
    container types yet to be written - as long as they follows the above
    pattern.
*   You can use nested `ElementsAre*()` to match nested (multi-dimensional)
    containers.
*   If the container is passed by pointer instead of by reference, just write
    `Pointee(ElementsAre*(...))`.
*   The order of elements *matters* for `ElementsAre*()`. If you are using it
    with containers whose element order are undefined (e.g. `hash_map`) you
    should use `WhenSorted` around `ElementsAre`.

#### Sharing Matchers

Under the hood, a gMock matcher object consists of a pointer to a ref-counted
implementation object. Copying matchers is allowed and very efficient, as only
the pointer is copied. When the last matcher that references the implementation
object dies, the implementation object will be deleted.

Therefore, if you have some complex matcher that you want to use again and
again, there is no need to build it everytime. Just assign it to a matcher
variable and use that variable repeatedly! For example,

```cpp
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Le;
using ::testing::Matcher;
...
  Matcher<int> in_range = AllOf(Gt(5), Le(10));
  ... use in_range as a matcher in multiple EXPECT_CALLs ...
```

#### Matchers must have no side-effects {#PureMatchers}

WARNING: gMock does not guarantee when or how many times a matcher will be
invoked. Therefore, all matchers must be *purely functional*: they cannot have
any side effects, and the match result must not depend on anything other than
the matcher's parameters and the value being matched.

This requirement must be satisfied no matter how a matcher is defined (e.g., if
it is one of the standard matchers, or a custom matcher). In particular, a
matcher can never call a mock function, as that will affect the state of the
mock object and gMock.

### Setting Expectations

#### Knowing When to Expect {#UseOnCall}

<!-- GOOGLETEST_CM0018 DO NOT DELETE -->

**`ON_CALL`** is likely the *single most under-utilized construct* in gMock.

There are basically two constructs for defining the behavior of a mock object:
`ON_CALL` and `EXPECT_CALL`. The difference? `ON_CALL` defines what happens when
a mock method is called, but <em>doesn't imply any expectation on the method
being called</em>. `EXPECT_CALL` not only defines the behavior, but also sets an
expectation that <em>the method will be called with the given arguments, for the
given number of times</em> (and *in the given order* when you specify the order
too).

Since `EXPECT_CALL` does more, isn't it better than `ON_CALL`? Not really. Every
`EXPECT_CALL` adds a constraint on the behavior of the code under test. Having
more constraints than necessary is *baaad* - even worse than not having enough
constraints.

This may be counter-intuitive. How could tests that verify more be worse than
tests that verify less? Isn't verification the whole point of tests?

The answer lies in *what* a test should verify. **A good test verifies the
contract of the code.** If a test over-specifies, it doesn't leave enough
freedom to the implementation. As a result, changing the implementation without
breaking the contract (e.g. refactoring and optimization), which should be
perfectly fine to do, can break such tests. Then you have to spend time fixing
them, only to see them broken again the next time the implementation is changed.

Keep in mind that one doesn't have to verify more than one property in one test.
In fact, **it's a good style to verify only one thing in one test.** If you do
that, a bug will likely break only one or two tests instead of dozens (which
case would you rather debug?). If you are also in the habit of giving tests
descriptive names that tell what they verify, you can often easily guess what's
wrong just from the test log itself.

So use `ON_CALL` by default, and only use `EXPECT_CALL` when you actually intend
to verify that the call is made. For example, you may have a bunch of `ON_CALL`s
in your test fixture to set the common mock behavior shared by all tests in the
same group, and write (scarcely) different `EXPECT_CALL`s in different `TEST_F`s
to verify different aspects of the code's behavior. Compared with the style
where each `TEST` has many `EXPECT_CALL`s, this leads to tests that are more
resilient to implementational changes (and thus less likely to require
maintenance) and makes the intent of the tests more obvious (so they are easier
to maintain when you do need to maintain them).

If you are bothered by the "Uninteresting mock function call" message printed
when a mock method without an `EXPECT_CALL` is called, you may use a `NiceMock`
instead to suppress all such messages for the mock object, or suppress the
message for specific methods by adding `EXPECT_CALL(...).Times(AnyNumber())`. DO
NOT suppress it by blindly adding an `EXPECT_CALL(...)`, or you'll have a test
that's a pain to maintain.

#### Ignoring Uninteresting Calls

If you are not interested in how a mock method is called, just don't say
anything about it. In this case, if the method is ever called, gMock will
perform its default action to allow the test program to continue. If you are not
happy with the default action taken by gMock, you can override it using
`DefaultValue<T>::Set()` (described [here](#DefaultValue)) or `ON_CALL()`.

Please note that once you expressed interest in a particular mock method (via
`EXPECT_CALL()`), all invocations to it must match some expectation. If this
function is called but the arguments don't match any `EXPECT_CALL()` statement,
it will be an error.

#### Disallowing Unexpected Calls

If a mock method shouldn't be called at all, explicitly say so:

```cpp
using ::testing::_;
...
  EXPECT_CALL(foo, Bar(_))
      .Times(0);
```

If some calls to the method are allowed, but the rest are not, just list all the
expected calls:

```cpp
using ::testing::AnyNumber;
using ::testing::Gt;
...
  EXPECT_CALL(foo, Bar(5));
  EXPECT_CALL(foo, Bar(Gt(10)))
      .Times(AnyNumber());
```

A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` statements
will be an error.

#### Understanding Uninteresting vs Unexpected Calls {#uninteresting-vs-unexpected}

*Uninteresting* calls and *unexpected* calls are different concepts in gMock.
*Very* different.

A call `x.Y(...)` is **uninteresting** if there's *not even a single*
`EXPECT_CALL(x, Y(...))` set. In other words, the test isn't interested in the
`x.Y()` method at all, as evident in that the test doesn't care to say anything
about it.

A call `x.Y(...)` is **unexpected** if there are *some* `EXPECT_CALL(x,
Y(...))`s set, but none of them matches the call. Put another way, the test is
interested in the `x.Y()` method (therefore it explicitly sets some
`EXPECT_CALL` to verify how it's called); however, the verification fails as the
test doesn't expect this particular call to happen.

**An unexpected call is always an error,** as the code under test doesn't behave
the way the test expects it to behave.

**By default, an uninteresting call is not an error,** as it violates no
constraint specified by the test. (gMock's philosophy is that saying nothing
means there is no constraint.) However, it leads to a warning, as it *might*
indicate a problem (e.g. the test author might have forgotten to specify a
constraint).

In gMock, `NiceMock` and `StrictMock` can be used to make a mock class "nice" or
"strict". How does this affect uninteresting calls and unexpected calls?

A **nice mock** suppresses uninteresting call *warnings*. It is less chatty than
the default mock, but otherwise is the same. If a test fails with a default
mock, it will also fail using a nice mock instead. And vice versa. Don't expect
making a mock nice to change the test's result.

A **strict mock** turns uninteresting call warnings into errors. So making a
mock strict may change the test's result.

Let's look at an example:

```cpp
TEST(...) {
  NiceMock<MockDomainRegistry> mock_registry;
  EXPECT_CALL(mock_registry, GetDomainOwner("google.com"))
          .WillRepeatedly(Return("Larry Page"));

  // Use mock_registry in code under test.
  ... &mock_registry ...
}
```

The sole `EXPECT_CALL` here says that all calls to `GetDomainOwner()` must have
`"google.com"` as the argument. If `GetDomainOwner("yahoo.com")` is called, it
will be an unexpected call, and thus an error. *Having a nice mock doesn't
change the severity of an unexpected call.*

So how do we tell gMock that `GetDomainOwner()` can be called with some other
arguments as well? The standard technique is to add a "catch all" `EXPECT_CALL`:

```cpp
  EXPECT_CALL(mock_registry, GetDomainOwner(_))
        .Times(AnyNumber());  // catches all other calls to this method.
  EXPECT_CALL(mock_registry, GetDomainOwner("google.com"))
        .WillRepeatedly(Return("Larry Page"));
```

Remember that `_` is the wildcard matcher that matches anything. With this, if
`GetDomainOwner("google.com")` is called, it will do what the second
`EXPECT_CALL` says; if it is called with a different argument, it will do what
the first `EXPECT_CALL` says.

Note that the order of the two `EXPECT_CALL`s is important, as a newer
`EXPECT_CALL` takes precedence over an older one.

For more on uninteresting calls, nice mocks, and strict mocks, read
["The Nice, the Strict, and the Naggy"](#NiceStrictNaggy).

#### Ignoring Uninteresting Arguments {#ParameterlessExpectations}

If your test doesn't care about the parameters (it only cares about the number
or order of calls), you can often simply omit the parameter list:

```cpp
  // Expect foo.Bar( ... ) twice with any arguments.
  EXPECT_CALL(foo, Bar).Times(2);

  // Delegate to the given method whenever the factory is invoked.
  ON_CALL(foo_factory, MakeFoo)
      .WillByDefault(&BuildFooForTest);
```

This functionality is only available when a method is not overloaded; to prevent
unexpected behavior it is a compilation error to try to set an expectation on a
method where the specific overload is ambiguous. You can work around this by
supplying a [simpler mock interface](#SimplerInterfaces) than the mocked class
provides.

This pattern is also useful when the arguments are interesting, but match logic
is substantially complex. You can leave the argument list unspecified and use
SaveArg actions to [save the values for later verification](#SaveArgVerify). If
you do that, you can easily differentiate calling the method the wrong number of
times from calling it with the wrong arguments.

#### Expecting Ordered Calls {#OrderedCalls}

Although an `EXPECT_CALL()` statement defined earlier takes precedence when
gMock tries to match a function call with an expectation, by default calls don't
have to happen in the order `EXPECT_CALL()` statements are written. For example,
if the arguments match the matchers in the third `EXPECT_CALL()`, but not those
in the first two, then the third expectation will be used.

If you would rather have all calls occur in the order of the expectations, put
the `EXPECT_CALL()` statements in a block where you define a variable of type
`InSequence`:

```cpp
using ::testing::_;
using ::testing::InSequence;

  {
    InSequence s;

    EXPECT_CALL(foo, DoThis(5));
    EXPECT_CALL(bar, DoThat(_))
        .Times(2);
    EXPECT_CALL(foo, DoThis(6));
  }
```

In this example, we expect a call to `foo.DoThis(5)`, followed by two calls to
`bar.DoThat()` where the argument can be anything, which are in turn followed by
a call to `foo.DoThis(6)`. If a call occurred out-of-order, gMock will report an
error.

#### Expecting Partially Ordered Calls {#PartialOrder}

Sometimes requiring everything to occur in a predetermined order can lead to
brittle tests. For example, we may care about `A` occurring before both `B` and
`C`, but aren't interested in the relative order of `B` and `C`. In this case,
the test should reflect our real intent, instead of being overly constraining.

gMock allows you to impose an arbitrary DAG (directed acyclic graph) on the
calls. One way to express the DAG is to use the [After](#AfterClause) clause of
`EXPECT_CALL`.

Another way is via the `InSequence()` clause (not the same as the `InSequence`
class), which we borrowed from jMock 2. It's less flexible than `After()`, but
more convenient when you have long chains of sequential calls, as it doesn't
require you to come up with different names for the expectations in the chains.
Here's how it works:

If we view `EXPECT_CALL()` statements as nodes in a graph, and add an edge from
node A to node B wherever A must occur before B, we can get a DAG. We use the
term "sequence" to mean a directed path in this DAG. Now, if we decompose the
DAG into sequences, we just need to know which sequences each `EXPECT_CALL()`
belongs to in order to be able to reconstruct the original DAG.

So, to specify the partial order on the expectations we need to do two things:
first to define some `Sequence` objects, and then for each `EXPECT_CALL()` say
which `Sequence` objects it is part of.

Expectations in the same sequence must occur in the order they are written. For
example,

```cpp
using ::testing::Sequence;
...
  Sequence s1, s2;

  EXPECT_CALL(foo, A())
      .InSequence(s1, s2);
  EXPECT_CALL(bar, B())
      .InSequence(s1);
  EXPECT_CALL(bar, C())
      .InSequence(s2);
  EXPECT_CALL(foo, D())
      .InSequence(s2);
```

specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`):

```text
       +---> B
       |
  A ---|
       |
        +---> C ---> D
```

This means that A must occur before B and C, and C must occur before D. There's
no restriction about the order other than these.

#### Controlling When an Expectation Retires

When a mock method is called, gMock only considers expectations that are still
active. An expectation is active when created, and becomes inactive (aka
*retires*) when a call that has to occur later has occurred. For example, in

```cpp
using ::testing::_;
using ::testing::Sequence;
...
  Sequence s1, s2;

  EXPECT_CALL(log, Log(WARNING, _, "File too large."))      // #1
      .Times(AnyNumber())
      .InSequence(s1, s2);
  EXPECT_CALL(log, Log(WARNING, _, "Data set is empty."))   // #2
      .InSequence(s1);
  EXPECT_CALL(log, Log(WARNING, _, "User not found."))      // #3
      .InSequence(s2);
```

as soon as either #2 or #3 is matched, #1 will retire. If a warning `"File too
large."` is logged after this, it will be an error.

Note that an expectation doesn't retire automatically when it's saturated. For
example,

```cpp
using ::testing::_;
...
  EXPECT_CALL(log, Log(WARNING, _, _));                     // #1
  EXPECT_CALL(log, Log(WARNING, _, "File too large."));     // #2
```

says that there will be exactly one warning with the message `"File too
large."`. If the second warning contains this message too, #2 will match again
and result in an upper-bound-violated error.

If this is not what you want, you can ask an expectation to retire as soon as it
becomes saturated:

```cpp
using ::testing::_;
...
  EXPECT_CALL(log, Log(WARNING, _, _));                     // #1
  EXPECT_CALL(log, Log(WARNING, _, "File too large."))      // #2
      .RetiresOnSaturation();
```

Here #2 can be used only once, so if you have two warnings with the message
`"File too large."`, the first will match #2 and the second will match #1 -
there will be no error.

### Using Actions

#### Returning References from Mock Methods

If a mock function's return type is a reference, you need to use `ReturnRef()`
instead of `Return()` to return a result:

```cpp
using ::testing::ReturnRef;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(Bar&, GetBar, (), (override));
};
...
  MockFoo foo;
  Bar bar;
  EXPECT_CALL(foo, GetBar())
      .WillOnce(ReturnRef(bar));
...
```

#### Returning Live Values from Mock Methods

The `Return(x)` action saves a copy of `x` when the action is created, and
always returns the same value whenever it's executed. Sometimes you may want to
instead return the *live* value of `x` (i.e. its value at the time when the
action is *executed*.). Use either `ReturnRef()` or `ReturnPointee()` for this
purpose.

If the mock function's return type is a reference, you can do it using
`ReturnRef(x)`, as shown in the previous recipe ("Returning References from Mock
Methods"). However, gMock doesn't let you use `ReturnRef()` in a mock function
whose return type is not a reference, as doing that usually indicates a user
error. So, what shall you do?

Though you may be tempted, DO NOT use `ByRef()`:

```cpp
using testing::ByRef;
using testing::Return;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(int, GetValue, (), (override));
};
...
  int x = 0;
  MockFoo foo;
  EXPECT_CALL(foo, GetValue())
      .WillRepeatedly(Return(ByRef(x)));  // Wrong!
  x = 42;
  EXPECT_EQ(42, foo.GetValue());
```

Unfortunately, it doesn't work here. The above code will fail with error:

```text
Value of: foo.GetValue()
  Actual: 0
Expected: 42
```

The reason is that `Return(*value*)` converts `value` to the actual return type
of the mock function at the time when the action is *created*, not when it is
*executed*. (This behavior was chosen for the action to be safe when `value` is
a proxy object that references some temporary objects.) As a result, `ByRef(x)`
is converted to an `int` value (instead of a `const int&`) when the expectation
is set, and `Return(ByRef(x))` will always return 0.

`ReturnPointee(pointer)` was provided to solve this problem specifically. It
returns the value pointed to by `pointer` at the time the action is *executed*:

```cpp
using testing::ReturnPointee;
...
  int x = 0;
  MockFoo foo;
  EXPECT_CALL(foo, GetValue())
      .WillRepeatedly(ReturnPointee(&x));  // Note the & here.
  x = 42;
  EXPECT_EQ(42, foo.GetValue());  // This will succeed now.
```

#### Combining Actions

Want to do more than one thing when a function is called? That's fine. `DoAll()`
allow you to do sequence of actions every time. Only the return value of the
last action in the sequence will be used.

```cpp
using ::testing::_;
using ::testing::DoAll;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(bool, Bar, (int n), (override));
};
...
  EXPECT_CALL(foo, Bar(_))
      .WillOnce(DoAll(action_1,
                      action_2,
                      ...
                      action_n));
```

#### Verifying Complex Arguments {#SaveArgVerify}

If you want to verify that a method is called with a particular argument but the
match criteria is complex, it can be difficult to distinguish between
cardinality failures (calling the method the wrong number of times) and argument
match failures. Similarly, if you are matching multiple parameters, it may not
be easy to distinguishing which argument failed to match. For example:

```cpp
  // Not ideal: this could fail because of a problem with arg1 or arg2, or maybe
  // just the method wasn't called.
  EXPECT_CALL(foo, SendValues(_, ElementsAre(1, 4, 4, 7), EqualsProto( ... )));
```

You can instead save the arguments and test them individually:

```cpp
  EXPECT_CALL(foo, SendValues)
      .WillOnce(DoAll(SaveArg<1>(&actual_array), SaveArg<2>(&actual_proto)));
  ... run the test
  EXPECT_THAT(actual_array, ElementsAre(1, 4, 4, 7));
  EXPECT_THAT(actual_proto, EqualsProto( ... ));
```

#### Mocking Side Effects {#MockingSideEffects}

Sometimes a method exhibits its effect not via returning a value but via side
effects. For example, it may change some global state or modify an output
argument. To mock side effects, in general you can define your own action by
implementing `::testing::ActionInterface`.

If all you need to do is to change an output argument, the built-in
`SetArgPointee()` action is convenient:

```cpp
using ::testing::_;
using ::testing::SetArgPointee;

class MockMutator : public Mutator {
 public:
  MOCK_METHOD(void, Mutate, (bool mutate, int* value), (override));
  ...
}
...
  MockMutator mutator;
  EXPECT_CALL(mutator, Mutate(true, _))
      .WillOnce(SetArgPointee<1>(5));
```

In this example, when `mutator.Mutate()` is called, we will assign 5 to the
`int` variable pointed to by argument #1 (0-based).

`SetArgPointee()` conveniently makes an internal copy of the value you pass to
it, removing the need to keep the value in scope and alive. The implication
however is that the value must have a copy constructor and assignment operator.

If the mock method also needs to return a value as well, you can chain
`SetArgPointee()` with `Return()` using `DoAll()`, remembering to put the
`Return()` statement last:

```cpp
using ::testing::_;
using ::testing::Return;
using ::testing::SetArgPointee;

class MockMutator : public Mutator {
 public:
  ...
  MOCK_METHOD(bool, MutateInt, (int* value), (override));
}
...
  MockMutator mutator;
  EXPECT_CALL(mutator, MutateInt(_))
      .WillOnce(DoAll(SetArgPointee<0>(5),
                      Return(true)));
```

Note, however, that if you use the `ReturnOKWith()` method, it will override the
values provided by `SetArgPointee()` in the response parameters of your function
call.

If the output argument is an array, use the `SetArrayArgument<N>(first, last)`
action instead. It copies the elements in source range `[first, last)` to the
array pointed to by the `N`-th (0-based) argument:

```cpp
using ::testing::NotNull;
using ::testing::SetArrayArgument;

class MockArrayMutator : public ArrayMutator {
 public:
  MOCK_METHOD(void, Mutate, (int* values, int num_values), (override));
  ...
}
...
  MockArrayMutator mutator;
  int values[5] = {1, 2, 3, 4, 5};
  EXPECT_CALL(mutator, Mutate(NotNull(), 5))
      .WillOnce(SetArrayArgument<0>(values, values + 5));
```

This also works when the argument is an output iterator:

```cpp
using ::testing::_;
using ::testing::SetArrayArgument;

class MockRolodex : public Rolodex {
 public:
  MOCK_METHOD(void, GetNames, (std::back_insert_iterator<vector<string>>),
              (override));
  ...
}
...
  MockRolodex rolodex;
  vector<string> names;
  names.push_back("George");
  names.push_back("John");
  names.push_back("Thomas");
  EXPECT_CALL(rolodex, GetNames(_))
      .WillOnce(SetArrayArgument<0>(names.begin(), names.end()));
```

#### Changing a Mock Object's Behavior Based on the State

If you expect a call to change the behavior of a mock object, you can use
`::testing::InSequence` to specify different behaviors before and after the
call:

```cpp
using ::testing::InSequence;
using ::testing::Return;

...
  {
     InSequence seq;
     EXPECT_CALL(my_mock, IsDirty())
         .WillRepeatedly(Return(true));
     EXPECT_CALL(my_mock, Flush());
     EXPECT_CALL(my_mock, IsDirty())
         .WillRepeatedly(Return(false));
  }
  my_mock.FlushIfDirty();
```

This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called
and return `false` afterwards.

If the behavior change is more complex, you can store the effects in a variable
and make a mock method get its return value from that variable:

```cpp
using ::testing::_;
using ::testing::SaveArg;
using ::testing::Return;

ACTION_P(ReturnPointee, p) { return *p; }
...
  int previous_value = 0;
  EXPECT_CALL(my_mock, GetPrevValue)
      .WillRepeatedly(ReturnPointee(&previous_value));
  EXPECT_CALL(my_mock, UpdateValue)
      .WillRepeatedly(SaveArg<0>(&previous_value));
  my_mock.DoSomethingToUpdateValue();
```

Here `my_mock.GetPrevValue()` will always return the argument of the last
`UpdateValue()` call.

#### Setting the Default Value for a Return Type {#DefaultValue}

If a mock method's return type is a built-in C++ type or pointer, by default it
will return 0 when invoked. Also, in C++ 11 and above, a mock method whose
return type has a default constructor will return a default-constructed value by
default. You only need to specify an action if this default value doesn't work
for you.

Sometimes, you may want to change this default value, or you may want to specify
a default value for types gMock doesn't know about. You can do this using the
`::testing::DefaultValue` class template:

```cpp
using ::testing::DefaultValue;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(Bar, CalculateBar, (), (override));
};


...
  Bar default_bar;
  // Sets the default return value for type Bar.
  DefaultValue<Bar>::Set(default_bar);

  MockFoo foo;

  // We don't need to specify an action here, as the default
  // return value works for us.
  EXPECT_CALL(foo, CalculateBar());

  foo.CalculateBar();  // This should return default_bar.

  // Unsets the default return value.
  DefaultValue<Bar>::Clear();
```

Please note that changing the default value for a type can make you tests hard
to understand. We recommend you to use this feature judiciously. For example,
you may want to make sure the `Set()` and `Clear()` calls are right next to the
code that uses your mock.

#### Setting the Default Actions for a Mock Method

You've learned how to change the default value of a given type. However, this
may be too coarse for your purpose: perhaps you have two mock methods with the
same return type and you want them to have different behaviors. The `ON_CALL()`
macro allows you to customize your mock's behavior at the method level:

```cpp
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Gt;
using ::testing::Return;
...
  ON_CALL(foo, Sign(_))
      .WillByDefault(Return(-1));
  ON_CALL(foo, Sign(0))
      .WillByDefault(Return(0));
  ON_CALL(foo, Sign(Gt(0)))
      .WillByDefault(Return(1));

  EXPECT_CALL(foo, Sign(_))
      .Times(AnyNumber());

  foo.Sign(5);   // This should return 1.
  foo.Sign(-9);  // This should return -1.
  foo.Sign(0);   // This should return 0.
```

As you may have guessed, when there are more than one `ON_CALL()` statements,
the newer ones in the order take precedence over the older ones. In other words,
the **last** one that matches the function arguments will be used. This matching
order allows you to set up the common behavior in a mock object's constructor or
the test fixture's set-up phase and specialize the mock's behavior later.

Note that both `ON_CALL` and `EXPECT_CALL` have the same "later statements take
precedence" rule, but they don't interact. That is, `EXPECT_CALL`s have their
own precedence order distinct from the `ON_CALL` precedence order.

#### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions}

If the built-in actions don't suit you, you can use an existing callable
(function, `std::function`, method, functor, lambda as an action.

<!-- GOOGLETEST_CM0024 DO NOT DELETE -->

```cpp
using ::testing::_; using ::testing::Invoke;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(int, Sum, (int x, int y), (override));
  MOCK_METHOD(bool, ComplexJob, (int x), (override));
};

int CalculateSum(int x, int y) { return x + y; }
int Sum3(int x, int y, int z) { return x + y + z; }

class Helper {
 public:
  bool ComplexJob(int x);
};

...
  MockFoo foo;
  Helper helper;
  EXPECT_CALL(foo, Sum(_, _))
      .WillOnce(&CalculateSum)
      .WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1)));
  EXPECT_CALL(foo, ComplexJob(_))
      .WillOnce(Invoke(&helper, &Helper::ComplexJob));
      .WillRepeatedly([](int x) { return x > 0; });

  foo.Sum(5, 6);         // Invokes CalculateSum(5, 6).
  foo.Sum(2, 3);         // Invokes Sum3(1, 2, 3).
  foo.ComplexJob(10);    // Invokes helper.ComplexJob(10).
  foo.ComplexJob(-1);    // Invokes the inline lambda.
```

The only requirement is that the type of the function, etc must be *compatible*
with the signature of the mock function, meaning that the latter's arguments can
be implicitly converted to the corresponding arguments of the former, and the
former's return type can be implicitly converted to that of the latter. So, you
can invoke something whose type is *not* exactly the same as the mock function,
as long as it's safe to do so - nice, huh?

**`Note:`{.escaped}**

*   The action takes ownership of the callback and will delete it when the
    action itself is destructed.
*   If the type of a callback is derived from a base callback type `C`, you need
    to implicitly cast it to `C` to resolve the overloading, e.g.

    ```cpp
    using ::testing::Invoke;
    ...
      ResultCallback<bool>* is_ok = ...;
      ... Invoke(is_ok) ...;  // This works.

      BlockingClosure* done = new BlockingClosure;
      ... Invoke(implicit_cast<Closure*>(done)) ...;  // The cast is necessary.
    ```

#### Using Functions with Extra Info as Actions

The function or functor you call using `Invoke()` must have the same number of
arguments as the mock function you use it for. Sometimes you may have a function
that takes more arguments, and you are willing to pass in the extra arguments
yourself to fill the gap. You can do this in gMock using callbacks with
pre-bound arguments. Here's an example:

```cpp
using ::testing::Invoke;

class MockFoo : public Foo {
 public:
  MOCK_METHOD(char, DoThis, (int n), (override));
};

char SignOfSum(int x, int y) {
  const int sum = x + y;
  return (sum > 0) ? '+' : (sum < 0) ? '-' : '0';
}

TEST_F(FooTest, Test) {
  MockFoo foo;

  EXPECT_CALL(foo, DoThis(2))