build_api: add Tot Firmware Builder service

To support building firmware targets on ToT in a more lightweight manner,
add a new build api that will simply call into a firmware_builder.py that
is specified by path.

See also go/cros-tot-fw-builder

BUG=b:169178847
TEST=none

Change-Id: I3790dc83c1e50b51b5cbadeee5c504978fd95693
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/proto/+/2430167
Reviewed-by: Alex Klein <saklein@chromium.org>
Commit-Queue: Jett Rink <jettrink@chromium.org>
diff --git a/go/chromite/api/firmware.pb.go b/go/chromite/api/firmware.pb.go
new file mode 100644
index 0000000..580e6cd
--- /dev/null
+++ b/go/chromite/api/firmware.pb.go
@@ -0,0 +1,819 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: chromite/api/firmware.proto
+
+package api
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+
+// List of known location that firmware can be built from
+type FwLocation int32
+
+const (
+	FwLocation_FW_LOCATION_UNKNOWN FwLocation = 0
+	FwLocation_PLATFORM_EC         FwLocation = 1
+	FwLocation_PLATFORM_ZEPHYR     FwLocation = 2
+)
+
+var FwLocation_name = map[int32]string{
+	0: "FW_LOCATION_UNKNOWN",
+	1: "PLATFORM_EC",
+	2: "PLATFORM_ZEPHYR",
+}
+
+var FwLocation_value = map[string]int32{
+	"FW_LOCATION_UNKNOWN": 0,
+	"PLATFORM_EC":         1,
+	"PLATFORM_ZEPHYR":     2,
+}
+
+func (x FwLocation) String() string {
+	return proto.EnumName(FwLocation_name, int32(x))
+}
+
+func (FwLocation) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{0}
+}
+
+type FwBuildMetric_FwSection_FwRegion int32
+
+const (
+	FwBuildMetric_FwSection_FW_REGION_UNKNOWN FwBuildMetric_FwSection_FwRegion = 0
+	FwBuildMetric_FwSection_EC_RO             FwBuildMetric_FwSection_FwRegion = 1
+	FwBuildMetric_FwSection_EC_RW             FwBuildMetric_FwSection_FwRegion = 2
+	FwBuildMetric_FwSection_EC_RO_BSS         FwBuildMetric_FwSection_FwRegion = 3
+	FwBuildMetric_FwSection_EC_RW_BSS         FwBuildMetric_FwSection_FwRegion = 4
+	FwBuildMetric_FwSection_EC_SHARED_MEM     FwBuildMetric_FwSection_FwRegion = 5
+)
+
+var FwBuildMetric_FwSection_FwRegion_name = map[int32]string{
+	0: "FW_REGION_UNKNOWN",
+	1: "EC_RO",
+	2: "EC_RW",
+	3: "EC_RO_BSS",
+	4: "EC_RW_BSS",
+	5: "EC_SHARED_MEM",
+}
+
+var FwBuildMetric_FwSection_FwRegion_value = map[string]int32{
+	"FW_REGION_UNKNOWN": 0,
+	"EC_RO":             1,
+	"EC_RW":             2,
+	"EC_RO_BSS":         3,
+	"EC_RW_BSS":         4,
+	"EC_SHARED_MEM":     5,
+}
+
+func (x FwBuildMetric_FwSection_FwRegion) String() string {
+	return proto.EnumName(FwBuildMetric_FwSection_FwRegion_name, int32(x))
+}
+
+func (FwBuildMetric_FwSection_FwRegion) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{0, 0, 0}
+}
+
+// Metrics collected on every successful firmware build
+type FwBuildMetric struct {
+	// Lowercase name of the firmware target built. E.g. phaser
+	TargetName string `protobuf:"bytes,1,opt,name=target_name,json=targetName,proto3" json:"target_name,omitempty"`
+	// Lowercase name of the platform the firmware target belongs to. May be
+	// blank. E.g. octopus
+	PlatformName string `protobuf:"bytes,2,opt,name=platform_name,json=platformName,proto3" json:"platform_name,omitempty"`
+	// List of firmware sections and their free and total sizes in bytes
+	FwSection []*FwBuildMetric_FwSection `protobuf:"bytes,3,rep,name=fw_section,json=fwSection,proto3" json:"fw_section,omitempty"`
+	// Optional information related to a specific target type
+	//
+	// Types that are valid to be assigned to ImageType:
+	//	*FwBuildMetric_Zephyr
+	ImageType            isFwBuildMetric_ImageType `protobuf_oneof:"image_type"`
+	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
+	XXX_unrecognized     []byte                    `json:"-"`
+	XXX_sizecache        int32                     `json:"-"`
+}
+
+func (m *FwBuildMetric) Reset()         { *m = FwBuildMetric{} }
+func (m *FwBuildMetric) String() string { return proto.CompactTextString(m) }
+func (*FwBuildMetric) ProtoMessage()    {}
+func (*FwBuildMetric) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{0}
+}
+
+func (m *FwBuildMetric) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FwBuildMetric.Unmarshal(m, b)
+}
+func (m *FwBuildMetric) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FwBuildMetric.Marshal(b, m, deterministic)
+}
+func (m *FwBuildMetric) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FwBuildMetric.Merge(m, src)
+}
+func (m *FwBuildMetric) XXX_Size() int {
+	return xxx_messageInfo_FwBuildMetric.Size(m)
+}
+func (m *FwBuildMetric) XXX_DiscardUnknown() {
+	xxx_messageInfo_FwBuildMetric.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FwBuildMetric proto.InternalMessageInfo
+
+func (m *FwBuildMetric) GetTargetName() string {
+	if m != nil {
+		return m.TargetName
+	}
+	return ""
+}
+
+func (m *FwBuildMetric) GetPlatformName() string {
+	if m != nil {
+		return m.PlatformName
+	}
+	return ""
+}
+
+func (m *FwBuildMetric) GetFwSection() []*FwBuildMetric_FwSection {
+	if m != nil {
+		return m.FwSection
+	}
+	return nil
+}
+
+type isFwBuildMetric_ImageType interface {
+	isFwBuildMetric_ImageType()
+}
+
+type FwBuildMetric_Zephyr struct {
+	Zephyr *FwBuildMetric_ZephyrTarget `protobuf:"bytes,4,opt,name=zephyr,proto3,oneof"`
+}
+
+func (*FwBuildMetric_Zephyr) isFwBuildMetric_ImageType() {}
+
+func (m *FwBuildMetric) GetImageType() isFwBuildMetric_ImageType {
+	if m != nil {
+		return m.ImageType
+	}
+	return nil
+}
+
+func (m *FwBuildMetric) GetZephyr() *FwBuildMetric_ZephyrTarget {
+	if x, ok := m.GetImageType().(*FwBuildMetric_Zephyr); ok {
+		return x.Zephyr
+	}
+	return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*FwBuildMetric) XXX_OneofWrappers() []interface{} {
+	return []interface{}{
+		(*FwBuildMetric_Zephyr)(nil),
+	}
+}
+
+type FwBuildMetric_FwSection struct {
+	// Region as described in FMAP or linker script.
+	// E.g. EC_RO, EC_RW, EC_NVRAM, RO_BSS, RW_BSS, SHARED_MEM
+	Region FwBuildMetric_FwSection_FwRegion `protobuf:"varint,1,opt,name=region,proto3,enum=chromite.api.FwBuildMetric_FwSection_FwRegion" json:"region,omitempty"`
+	// The number of bytes used in this section
+	Used uint32 `protobuf:"varint,2,opt,name=used,proto3" json:"used,omitempty"`
+	// The total number of bytes available in this section
+	Total                uint32   `protobuf:"varint,3,opt,name=total,proto3" json:"total,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *FwBuildMetric_FwSection) Reset()         { *m = FwBuildMetric_FwSection{} }
+func (m *FwBuildMetric_FwSection) String() string { return proto.CompactTextString(m) }
+func (*FwBuildMetric_FwSection) ProtoMessage()    {}
+func (*FwBuildMetric_FwSection) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{0, 0}
+}
+
+func (m *FwBuildMetric_FwSection) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FwBuildMetric_FwSection.Unmarshal(m, b)
+}
+func (m *FwBuildMetric_FwSection) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FwBuildMetric_FwSection.Marshal(b, m, deterministic)
+}
+func (m *FwBuildMetric_FwSection) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FwBuildMetric_FwSection.Merge(m, src)
+}
+func (m *FwBuildMetric_FwSection) XXX_Size() int {
+	return xxx_messageInfo_FwBuildMetric_FwSection.Size(m)
+}
+func (m *FwBuildMetric_FwSection) XXX_DiscardUnknown() {
+	xxx_messageInfo_FwBuildMetric_FwSection.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FwBuildMetric_FwSection proto.InternalMessageInfo
+
+func (m *FwBuildMetric_FwSection) GetRegion() FwBuildMetric_FwSection_FwRegion {
+	if m != nil {
+		return m.Region
+	}
+	return FwBuildMetric_FwSection_FW_REGION_UNKNOWN
+}
+
+func (m *FwBuildMetric_FwSection) GetUsed() uint32 {
+	if m != nil {
+		return m.Used
+	}
+	return 0
+}
+
+func (m *FwBuildMetric_FwSection) GetTotal() uint32 {
+	if m != nil {
+		return m.Total
+	}
+	return 0
+}
+
+// Version number components: "major.minor.tiny".
+type FwBuildMetric_Version struct {
+	Major                uint32   `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
+	Minor                uint32   `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
+	Tiny                 uint32   `protobuf:"varint,3,opt,name=tiny,proto3" json:"tiny,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *FwBuildMetric_Version) Reset()         { *m = FwBuildMetric_Version{} }
+func (m *FwBuildMetric_Version) String() string { return proto.CompactTextString(m) }
+func (*FwBuildMetric_Version) ProtoMessage()    {}
+func (*FwBuildMetric_Version) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{0, 1}
+}
+
+func (m *FwBuildMetric_Version) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FwBuildMetric_Version.Unmarshal(m, b)
+}
+func (m *FwBuildMetric_Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FwBuildMetric_Version.Marshal(b, m, deterministic)
+}
+func (m *FwBuildMetric_Version) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FwBuildMetric_Version.Merge(m, src)
+}
+func (m *FwBuildMetric_Version) XXX_Size() int {
+	return xxx_messageInfo_FwBuildMetric_Version.Size(m)
+}
+func (m *FwBuildMetric_Version) XXX_DiscardUnknown() {
+	xxx_messageInfo_FwBuildMetric_Version.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FwBuildMetric_Version proto.InternalMessageInfo
+
+func (m *FwBuildMetric_Version) GetMajor() uint32 {
+	if m != nil {
+		return m.Major
+	}
+	return 0
+}
+
+func (m *FwBuildMetric_Version) GetMinor() uint32 {
+	if m != nil {
+		return m.Minor
+	}
+	return 0
+}
+
+func (m *FwBuildMetric_Version) GetTiny() uint32 {
+	if m != nil {
+		return m.Tiny
+	}
+	return 0
+}
+
+// Zephyr-base firmware target related build metrics
+type FwBuildMetric_ZephyrTarget struct {
+	// The version of the Zephyr kernel used during build
+	KernelVersion        *FwBuildMetric_Version `protobuf:"bytes,1,opt,name=kernel_version,json=kernelVersion,proto3" json:"kernel_version,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}               `json:"-"`
+	XXX_unrecognized     []byte                 `json:"-"`
+	XXX_sizecache        int32                  `json:"-"`
+}
+
+func (m *FwBuildMetric_ZephyrTarget) Reset()         { *m = FwBuildMetric_ZephyrTarget{} }
+func (m *FwBuildMetric_ZephyrTarget) String() string { return proto.CompactTextString(m) }
+func (*FwBuildMetric_ZephyrTarget) ProtoMessage()    {}
+func (*FwBuildMetric_ZephyrTarget) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{0, 2}
+}
+
+func (m *FwBuildMetric_ZephyrTarget) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FwBuildMetric_ZephyrTarget.Unmarshal(m, b)
+}
+func (m *FwBuildMetric_ZephyrTarget) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FwBuildMetric_ZephyrTarget.Marshal(b, m, deterministic)
+}
+func (m *FwBuildMetric_ZephyrTarget) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FwBuildMetric_ZephyrTarget.Merge(m, src)
+}
+func (m *FwBuildMetric_ZephyrTarget) XXX_Size() int {
+	return xxx_messageInfo_FwBuildMetric_ZephyrTarget.Size(m)
+}
+func (m *FwBuildMetric_ZephyrTarget) XXX_DiscardUnknown() {
+	xxx_messageInfo_FwBuildMetric_ZephyrTarget.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FwBuildMetric_ZephyrTarget proto.InternalMessageInfo
+
+func (m *FwBuildMetric_ZephyrTarget) GetKernelVersion() *FwBuildMetric_Version {
+	if m != nil {
+		return m.KernelVersion
+	}
+	return nil
+}
+
+// A list of FW metrics collected on every successful firmware build
+// Implementation note, this is a separate message since it serves as the
+// serialization base between the build_api end point and the entry point
+// in the firmware_builder.py
+type FwBuildMetricList struct {
+	Value                []*FwBuildMetric `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
+	XXX_unrecognized     []byte           `json:"-"`
+	XXX_sizecache        int32            `json:"-"`
+}
+
+func (m *FwBuildMetricList) Reset()         { *m = FwBuildMetricList{} }
+func (m *FwBuildMetricList) String() string { return proto.CompactTextString(m) }
+func (*FwBuildMetricList) ProtoMessage()    {}
+func (*FwBuildMetricList) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{1}
+}
+
+func (m *FwBuildMetricList) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FwBuildMetricList.Unmarshal(m, b)
+}
+func (m *FwBuildMetricList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FwBuildMetricList.Marshal(b, m, deterministic)
+}
+func (m *FwBuildMetricList) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FwBuildMetricList.Merge(m, src)
+}
+func (m *FwBuildMetricList) XXX_Size() int {
+	return xxx_messageInfo_FwBuildMetricList.Size(m)
+}
+func (m *FwBuildMetricList) XXX_DiscardUnknown() {
+	xxx_messageInfo_FwBuildMetricList.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FwBuildMetricList proto.InternalMessageInfo
+
+func (m *FwBuildMetricList) GetValue() []*FwBuildMetric {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+// Metrics collect on successful firmware unit test runs
+type FwTestMetric struct {
+	// Name of firmware test
+	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *FwTestMetric) Reset()         { *m = FwTestMetric{} }
+func (m *FwTestMetric) String() string { return proto.CompactTextString(m) }
+func (*FwTestMetric) ProtoMessage()    {}
+func (*FwTestMetric) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{2}
+}
+
+func (m *FwTestMetric) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FwTestMetric.Unmarshal(m, b)
+}
+func (m *FwTestMetric) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FwTestMetric.Marshal(b, m, deterministic)
+}
+func (m *FwTestMetric) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FwTestMetric.Merge(m, src)
+}
+func (m *FwTestMetric) XXX_Size() int {
+	return xxx_messageInfo_FwTestMetric.Size(m)
+}
+func (m *FwTestMetric) XXX_DiscardUnknown() {
+	xxx_messageInfo_FwTestMetric.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FwTestMetric proto.InternalMessageInfo
+
+func (m *FwTestMetric) GetName() string {
+	if m != nil {
+		return m.Name
+	}
+	return ""
+}
+
+// A list of FW metrics collected on every successful firmware unit test.
+// Implementation note, this is a separate message since it serves as the
+// serialization base between the build_api end point and the entry point
+// in the firmware_builder.py
+type FwTestMetricList struct {
+	Value                []*FwTestMetric `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
+	XXX_unrecognized     []byte          `json:"-"`
+	XXX_sizecache        int32           `json:"-"`
+}
+
+func (m *FwTestMetricList) Reset()         { *m = FwTestMetricList{} }
+func (m *FwTestMetricList) String() string { return proto.CompactTextString(m) }
+func (*FwTestMetricList) ProtoMessage()    {}
+func (*FwTestMetricList) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{3}
+}
+
+func (m *FwTestMetricList) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_FwTestMetricList.Unmarshal(m, b)
+}
+func (m *FwTestMetricList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_FwTestMetricList.Marshal(b, m, deterministic)
+}
+func (m *FwTestMetricList) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_FwTestMetricList.Merge(m, src)
+}
+func (m *FwTestMetricList) XXX_Size() int {
+	return xxx_messageInfo_FwTestMetricList.Size(m)
+}
+func (m *FwTestMetricList) XXX_DiscardUnknown() {
+	xxx_messageInfo_FwTestMetricList.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_FwTestMetricList proto.InternalMessageInfo
+
+func (m *FwTestMetricList) GetValue() []*FwTestMetric {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+type BuildAllTotFirmwareRequest struct {
+	// Location of firmware to build call into firmware_builder.py entry point.
+	// The `build` subcommand will be called
+	FirmwareLocation     FwLocation `protobuf:"varint,1,opt,name=firmware_location,json=firmwareLocation,proto3,enum=chromite.api.FwLocation" json:"firmware_location,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
+	XXX_unrecognized     []byte     `json:"-"`
+	XXX_sizecache        int32      `json:"-"`
+}
+
+func (m *BuildAllTotFirmwareRequest) Reset()         { *m = BuildAllTotFirmwareRequest{} }
+func (m *BuildAllTotFirmwareRequest) String() string { return proto.CompactTextString(m) }
+func (*BuildAllTotFirmwareRequest) ProtoMessage()    {}
+func (*BuildAllTotFirmwareRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{4}
+}
+
+func (m *BuildAllTotFirmwareRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_BuildAllTotFirmwareRequest.Unmarshal(m, b)
+}
+func (m *BuildAllTotFirmwareRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_BuildAllTotFirmwareRequest.Marshal(b, m, deterministic)
+}
+func (m *BuildAllTotFirmwareRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_BuildAllTotFirmwareRequest.Merge(m, src)
+}
+func (m *BuildAllTotFirmwareRequest) XXX_Size() int {
+	return xxx_messageInfo_BuildAllTotFirmwareRequest.Size(m)
+}
+func (m *BuildAllTotFirmwareRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_BuildAllTotFirmwareRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BuildAllTotFirmwareRequest proto.InternalMessageInfo
+
+func (m *BuildAllTotFirmwareRequest) GetFirmwareLocation() FwLocation {
+	if m != nil {
+		return m.FirmwareLocation
+	}
+	return FwLocation_FW_LOCATION_UNKNOWN
+}
+
+type BuildAllTotFirmwareResponse struct {
+	// Metrics collected on every successful firmware build
+	Metrics              *FwBuildMetricList `protobuf:"bytes,1,opt,name=metrics,proto3" json:"metrics,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}           `json:"-"`
+	XXX_unrecognized     []byte             `json:"-"`
+	XXX_sizecache        int32              `json:"-"`
+}
+
+func (m *BuildAllTotFirmwareResponse) Reset()         { *m = BuildAllTotFirmwareResponse{} }
+func (m *BuildAllTotFirmwareResponse) String() string { return proto.CompactTextString(m) }
+func (*BuildAllTotFirmwareResponse) ProtoMessage()    {}
+func (*BuildAllTotFirmwareResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{5}
+}
+
+func (m *BuildAllTotFirmwareResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_BuildAllTotFirmwareResponse.Unmarshal(m, b)
+}
+func (m *BuildAllTotFirmwareResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_BuildAllTotFirmwareResponse.Marshal(b, m, deterministic)
+}
+func (m *BuildAllTotFirmwareResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_BuildAllTotFirmwareResponse.Merge(m, src)
+}
+func (m *BuildAllTotFirmwareResponse) XXX_Size() int {
+	return xxx_messageInfo_BuildAllTotFirmwareResponse.Size(m)
+}
+func (m *BuildAllTotFirmwareResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_BuildAllTotFirmwareResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BuildAllTotFirmwareResponse proto.InternalMessageInfo
+
+func (m *BuildAllTotFirmwareResponse) GetMetrics() *FwBuildMetricList {
+	if m != nil {
+		return m.Metrics
+	}
+	return nil
+}
+
+type TestAllTotFirmwareRequest struct {
+	// Location of firmware to build call into firmware_builder.py entry point.
+	// The `test` subcommand will be called
+	FirmwareLocation     FwLocation `protobuf:"varint,1,opt,name=firmware_location,json=firmwareLocation,proto3,enum=chromite.api.FwLocation" json:"firmware_location,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
+	XXX_unrecognized     []byte     `json:"-"`
+	XXX_sizecache        int32      `json:"-"`
+}
+
+func (m *TestAllTotFirmwareRequest) Reset()         { *m = TestAllTotFirmwareRequest{} }
+func (m *TestAllTotFirmwareRequest) String() string { return proto.CompactTextString(m) }
+func (*TestAllTotFirmwareRequest) ProtoMessage()    {}
+func (*TestAllTotFirmwareRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{6}
+}
+
+func (m *TestAllTotFirmwareRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TestAllTotFirmwareRequest.Unmarshal(m, b)
+}
+func (m *TestAllTotFirmwareRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TestAllTotFirmwareRequest.Marshal(b, m, deterministic)
+}
+func (m *TestAllTotFirmwareRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TestAllTotFirmwareRequest.Merge(m, src)
+}
+func (m *TestAllTotFirmwareRequest) XXX_Size() int {
+	return xxx_messageInfo_TestAllTotFirmwareRequest.Size(m)
+}
+func (m *TestAllTotFirmwareRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_TestAllTotFirmwareRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TestAllTotFirmwareRequest proto.InternalMessageInfo
+
+func (m *TestAllTotFirmwareRequest) GetFirmwareLocation() FwLocation {
+	if m != nil {
+		return m.FirmwareLocation
+	}
+	return FwLocation_FW_LOCATION_UNKNOWN
+}
+
+type TestAllTotFirmwareResponse struct {
+	// Metrics collect on successfuly firmware unit test runs
+	Metrics              *FwTestMetricList `protobuf:"bytes,1,opt,name=metrics,proto3" json:"metrics,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
+	XXX_unrecognized     []byte            `json:"-"`
+	XXX_sizecache        int32             `json:"-"`
+}
+
+func (m *TestAllTotFirmwareResponse) Reset()         { *m = TestAllTotFirmwareResponse{} }
+func (m *TestAllTotFirmwareResponse) String() string { return proto.CompactTextString(m) }
+func (*TestAllTotFirmwareResponse) ProtoMessage()    {}
+func (*TestAllTotFirmwareResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_7e3de92302c5ee13, []int{7}
+}
+
+func (m *TestAllTotFirmwareResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_TestAllTotFirmwareResponse.Unmarshal(m, b)
+}
+func (m *TestAllTotFirmwareResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_TestAllTotFirmwareResponse.Marshal(b, m, deterministic)
+}
+func (m *TestAllTotFirmwareResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TestAllTotFirmwareResponse.Merge(m, src)
+}
+func (m *TestAllTotFirmwareResponse) XXX_Size() int {
+	return xxx_messageInfo_TestAllTotFirmwareResponse.Size(m)
+}
+func (m *TestAllTotFirmwareResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_TestAllTotFirmwareResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TestAllTotFirmwareResponse proto.InternalMessageInfo
+
+func (m *TestAllTotFirmwareResponse) GetMetrics() *FwTestMetricList {
+	if m != nil {
+		return m.Metrics
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterEnum("chromite.api.FwLocation", FwLocation_name, FwLocation_value)
+	proto.RegisterEnum("chromite.api.FwBuildMetric_FwSection_FwRegion", FwBuildMetric_FwSection_FwRegion_name, FwBuildMetric_FwSection_FwRegion_value)
+	proto.RegisterType((*FwBuildMetric)(nil), "chromite.api.FwBuildMetric")
+	proto.RegisterType((*FwBuildMetric_FwSection)(nil), "chromite.api.FwBuildMetric.FwSection")
+	proto.RegisterType((*FwBuildMetric_Version)(nil), "chromite.api.FwBuildMetric.Version")
+	proto.RegisterType((*FwBuildMetric_ZephyrTarget)(nil), "chromite.api.FwBuildMetric.ZephyrTarget")
+	proto.RegisterType((*FwBuildMetricList)(nil), "chromite.api.FwBuildMetricList")
+	proto.RegisterType((*FwTestMetric)(nil), "chromite.api.FwTestMetric")
+	proto.RegisterType((*FwTestMetricList)(nil), "chromite.api.FwTestMetricList")
+	proto.RegisterType((*BuildAllTotFirmwareRequest)(nil), "chromite.api.BuildAllTotFirmwareRequest")
+	proto.RegisterType((*BuildAllTotFirmwareResponse)(nil), "chromite.api.BuildAllTotFirmwareResponse")
+	proto.RegisterType((*TestAllTotFirmwareRequest)(nil), "chromite.api.TestAllTotFirmwareRequest")
+	proto.RegisterType((*TestAllTotFirmwareResponse)(nil), "chromite.api.TestAllTotFirmwareResponse")
+}
+
+func init() { proto.RegisterFile("chromite/api/firmware.proto", fileDescriptor_7e3de92302c5ee13) }
+
+var fileDescriptor_7e3de92302c5ee13 = []byte{
+	// 718 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xdf, 0x53, 0xda, 0x4e,
+	0x10, 0x37, 0x02, 0x2a, 0x0b, 0x68, 0x38, 0xfd, 0xce, 0x97, 0xc6, 0x4e, 0x75, 0xe2, 0x74, 0x4a,
+	0xfb, 0x10, 0x5a, 0x3a, 0xd3, 0xb1, 0x8f, 0x80, 0x49, 0xb5, 0xf2, 0xc3, 0x39, 0xa8, 0xb4, 0xbc,
+	0x64, 0x22, 0x1e, 0x18, 0x9b, 0x70, 0xe9, 0xe5, 0x90, 0xb1, 0x7f, 0x5e, 0xff, 0x99, 0x3e, 0xf5,
+	0xbd, 0x4f, 0x9d, 0x4e, 0x2e, 0x89, 0x02, 0x55, 0xea, 0x4b, 0xdf, 0x76, 0x37, 0x9f, 0xdd, 0xcf,
+	0x67, 0xf7, 0xf6, 0x72, 0xb0, 0xdd, 0xbf, 0x60, 0xd4, 0xb5, 0x39, 0x29, 0x59, 0x9e, 0x5d, 0x1a,
+	0xd8, 0xcc, 0x9d, 0x58, 0x8c, 0x68, 0x1e, 0xa3, 0x9c, 0xa2, 0x6c, 0xfc, 0x51, 0xb3, 0x3c, 0x5b,
+	0x79, 0x3c, 0x03, 0x3d, 0x1b, 0xdb, 0xce, 0xb9, 0x69, 0x79, 0x76, 0x88, 0x55, 0x7f, 0x25, 0x21,
+	0x67, 0x4c, 0xaa, 0x41, 0xb4, 0x41, 0x38, 0xb3, 0xfb, 0x68, 0x07, 0x32, 0xdc, 0x62, 0x43, 0xc2,
+	0xcd, 0x91, 0xe5, 0x92, 0x82, 0xb4, 0x2b, 0x15, 0xd3, 0x18, 0xc2, 0x50, 0xd3, 0x72, 0x09, 0xda,
+	0x83, 0x9c, 0xe7, 0x58, 0x7c, 0x40, 0x99, 0x1b, 0x42, 0x96, 0x05, 0x24, 0x1b, 0x07, 0x05, 0xe8,
+	0x00, 0x60, 0x30, 0x31, 0x7d, 0xd2, 0xe7, 0x36, 0x1d, 0x15, 0x12, 0xbb, 0x89, 0x62, 0xa6, 0xfc,
+	0x54, 0x9b, 0x16, 0xa6, 0xcd, 0xd0, 0x6a, 0xc6, 0xa4, 0x1d, 0x82, 0x71, 0x7a, 0x10, 0x9b, 0xa8,
+	0x0a, 0x2b, 0x5f, 0x89, 0x77, 0x71, 0xcd, 0x0a, 0xc9, 0x5d, 0xa9, 0x98, 0x29, 0x17, 0x17, 0x55,
+	0xe8, 0x09, 0x64, 0x47, 0x08, 0x3d, 0x5c, 0xc2, 0x51, 0xa6, 0xf2, 0x5d, 0x82, 0xf4, 0x4d, 0x71,
+	0x64, 0xc0, 0x0a, 0x23, 0xc3, 0x40, 0x53, 0xd0, 0xd8, 0x7a, 0x59, 0x7b, 0x90, 0x26, 0xcd, 0x98,
+	0x60, 0x91, 0x85, 0xa3, 0x6c, 0x84, 0x20, 0x39, 0xf6, 0xc9, 0xb9, 0xe8, 0x3d, 0x87, 0x85, 0x8d,
+	0xb6, 0x20, 0xc5, 0x29, 0xb7, 0x9c, 0x42, 0x42, 0x04, 0x43, 0x47, 0xbd, 0x80, 0xb5, 0x38, 0x1b,
+	0xfd, 0x07, 0x79, 0xa3, 0x6b, 0x62, 0xfd, 0xdd, 0x51, 0xab, 0x69, 0x7e, 0x68, 0x1e, 0x37, 0x5b,
+	0xdd, 0xa6, 0xbc, 0x84, 0xd2, 0x90, 0xd2, 0x6b, 0x26, 0x6e, 0xc9, 0x52, 0x6c, 0x76, 0xe5, 0x65,
+	0x94, 0x83, 0xb4, 0x88, 0x9a, 0xd5, 0x76, 0x5b, 0x4e, 0xc4, 0x6e, 0x57, 0xb8, 0x49, 0x94, 0x87,
+	0x9c, 0x5e, 0x33, 0xdb, 0x87, 0x15, 0xac, 0x1f, 0x98, 0x0d, 0xbd, 0x21, 0xa7, 0x94, 0x23, 0x58,
+	0x3d, 0x25, 0xcc, 0x0f, 0x88, 0xb6, 0x20, 0xe5, 0x5a, 0x97, 0x94, 0x89, 0x2e, 0x73, 0x38, 0x74,
+	0x44, 0xd4, 0x1e, 0x51, 0x16, 0xa9, 0x0e, 0x9d, 0xa0, 0x15, 0x6e, 0x8f, 0xae, 0x23, 0xd5, 0xc2,
+	0x56, 0x7a, 0x90, 0x9d, 0x1e, 0x27, 0x7a, 0x0f, 0xeb, 0x9f, 0x09, 0x1b, 0x11, 0xc7, 0xbc, 0x0a,
+	0x19, 0x44, 0xe1, 0x4c, 0x79, 0x6f, 0xd1, 0xf8, 0x22, 0x31, 0x38, 0x17, 0xa6, 0x46, 0x6e, 0x35,
+	0x0b, 0x60, 0xbb, 0xd6, 0x90, 0x98, 0xfc, 0xda, 0x23, 0xaa, 0x01, 0xf9, 0x99, 0xac, 0xba, 0xed,
+	0x73, 0xf4, 0x0a, 0x52, 0x57, 0x96, 0x33, 0x0e, 0xb6, 0x2f, 0x58, 0x9c, 0xed, 0x05, 0x2c, 0x38,
+	0x44, 0xaa, 0x2a, 0x64, 0x8d, 0x49, 0x87, 0xf8, 0x3c, 0x5a, 0x63, 0x04, 0xc9, 0xa9, 0xfd, 0x15,
+	0xb6, 0x7a, 0x00, 0xf2, 0x34, 0x46, 0x50, 0xbd, 0x9c, 0xa5, 0x52, 0xe6, 0xa9, 0x6e, 0xe1, 0x31,
+	0x53, 0x1f, 0x14, 0xc1, 0x5f, 0x71, 0x9c, 0x0e, 0xe5, 0x46, 0x74, 0xf7, 0x30, 0xf9, 0x32, 0x26,
+	0x3e, 0x47, 0x3a, 0xe4, 0xe3, 0xeb, 0x68, 0x3a, 0xb4, 0x6f, 0xf1, 0xdb, 0x5d, 0x2b, 0xcc, 0xd7,
+	0xae, 0x47, 0xdf, 0xb1, 0x1c, 0xa7, 0xc4, 0x11, 0xf5, 0x23, 0x6c, 0xdf, 0x49, 0xe2, 0x7b, 0x74,
+	0xe4, 0x13, 0xf4, 0x16, 0x56, 0x5d, 0x21, 0xca, 0x8f, 0x0e, 0x62, 0x67, 0xc1, 0x88, 0x82, 0x3e,
+	0x71, 0x8c, 0x57, 0xcf, 0xe0, 0x51, 0xd0, 0xd3, 0x3f, 0x55, 0x7f, 0x0a, 0xca, 0x5d, 0x1c, 0x91,
+	0xf8, 0xfd, 0x79, 0xf1, 0x4f, 0xee, 0x1f, 0xfa, 0x8c, 0xf6, 0x17, 0xc7, 0x00, 0xb7, 0xbc, 0xe8,
+	0x7f, 0xd8, 0x34, 0xba, 0x66, 0xbd, 0x55, 0xab, 0x74, 0x66, 0xef, 0xd3, 0x06, 0x64, 0x4e, 0xea,
+	0x95, 0x8e, 0xd1, 0xc2, 0x0d, 0x53, 0xaf, 0xc9, 0x12, 0xda, 0x84, 0x8d, 0x9b, 0x40, 0x4f, 0x3f,
+	0x39, 0xfc, 0x84, 0xe5, 0xe5, 0xf2, 0x4f, 0x09, 0x36, 0x62, 0x6d, 0x6d, 0xc2, 0xae, 0xec, 0x3e,
+	0x41, 0x97, 0xb0, 0x79, 0xc7, 0xd8, 0xd1, 0xdc, 0x7f, 0xe7, 0xfe, 0xe3, 0x57, 0x9e, 0x3f, 0x00,
+	0x19, 0x8d, 0x61, 0x08, 0xe8, 0xcf, 0x21, 0xa1, 0x67, 0xb3, 0x05, 0xee, 0x3d, 0x2a, 0xa5, 0xf8,
+	0x77, 0x60, 0x48, 0xa4, 0xc8, 0xdf, 0x7e, 0x28, 0x59, 0x58, 0x8b, 0x4f, 0x49, 0x96, 0xaa, 0xfb,
+	0xbd, 0x37, 0x43, 0x1a, 0xe5, 0x8f, 0x5d, 0x8d, 0xb2, 0x61, 0x29, 0x76, 0xa8, 0x5f, 0xb2, 0x47,
+	0x03, 0x66, 0x95, 0xc4, 0xfb, 0x50, 0x1a, 0xd2, 0xd2, 0xf4, 0xfb, 0x71, 0xb6, 0x22, 0xc2, 0xaf,
+	0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x7f, 0x3f, 0x7e, 0x81, 0x06, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// FirmwareServiceClient is the client API for FirmwareService service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type FirmwareServiceClient interface {
+	// Builds all of the firmware targets on ToT at specified location
+	BuildAllTotFirmware(ctx context.Context, in *BuildAllTotFirmwareRequest, opts ...grpc.CallOption) (*BuildAllTotFirmwareResponse, error)
+	// Runs all of the firmware tests on ToT at specified location
+	TestAllTotFirmware(ctx context.Context, in *TestAllTotFirmwareRequest, opts ...grpc.CallOption) (*TestAllTotFirmwareResponse, error)
+}
+
+type firmwareServiceClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewFirmwareServiceClient(cc *grpc.ClientConn) FirmwareServiceClient {
+	return &firmwareServiceClient{cc}
+}
+
+func (c *firmwareServiceClient) BuildAllTotFirmware(ctx context.Context, in *BuildAllTotFirmwareRequest, opts ...grpc.CallOption) (*BuildAllTotFirmwareResponse, error) {
+	out := new(BuildAllTotFirmwareResponse)
+	err := c.cc.Invoke(ctx, "/chromite.api.FirmwareService/BuildAllTotFirmware", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *firmwareServiceClient) TestAllTotFirmware(ctx context.Context, in *TestAllTotFirmwareRequest, opts ...grpc.CallOption) (*TestAllTotFirmwareResponse, error) {
+	out := new(TestAllTotFirmwareResponse)
+	err := c.cc.Invoke(ctx, "/chromite.api.FirmwareService/TestAllTotFirmware", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// FirmwareServiceServer is the server API for FirmwareService service.
+type FirmwareServiceServer interface {
+	// Builds all of the firmware targets on ToT at specified location
+	BuildAllTotFirmware(context.Context, *BuildAllTotFirmwareRequest) (*BuildAllTotFirmwareResponse, error)
+	// Runs all of the firmware tests on ToT at specified location
+	TestAllTotFirmware(context.Context, *TestAllTotFirmwareRequest) (*TestAllTotFirmwareResponse, error)
+}
+
+// UnimplementedFirmwareServiceServer can be embedded to have forward compatible implementations.
+type UnimplementedFirmwareServiceServer struct {
+}
+
+func (*UnimplementedFirmwareServiceServer) BuildAllTotFirmware(ctx context.Context, req *BuildAllTotFirmwareRequest) (*BuildAllTotFirmwareResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method BuildAllTotFirmware not implemented")
+}
+func (*UnimplementedFirmwareServiceServer) TestAllTotFirmware(ctx context.Context, req *TestAllTotFirmwareRequest) (*TestAllTotFirmwareResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method TestAllTotFirmware not implemented")
+}
+
+func RegisterFirmwareServiceServer(s *grpc.Server, srv FirmwareServiceServer) {
+	s.RegisterService(&_FirmwareService_serviceDesc, srv)
+}
+
+func _FirmwareService_BuildAllTotFirmware_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(BuildAllTotFirmwareRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(FirmwareServiceServer).BuildAllTotFirmware(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/chromite.api.FirmwareService/BuildAllTotFirmware",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(FirmwareServiceServer).BuildAllTotFirmware(ctx, req.(*BuildAllTotFirmwareRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _FirmwareService_TestAllTotFirmware_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(TestAllTotFirmwareRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(FirmwareServiceServer).TestAllTotFirmware(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/chromite.api.FirmwareService/TestAllTotFirmware",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(FirmwareServiceServer).TestAllTotFirmware(ctx, req.(*TestAllTotFirmwareRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _FirmwareService_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "chromite.api.FirmwareService",
+	HandlerType: (*FirmwareServiceServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "BuildAllTotFirmware",
+			Handler:    _FirmwareService_BuildAllTotFirmware_Handler,
+		},
+		{
+			MethodName: "TestAllTotFirmware",
+			Handler:    _FirmwareService_TestAllTotFirmware_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "chromite/api/firmware.proto",
+}
diff --git a/src/chromite/api/firmware.proto b/src/chromite/api/firmware.proto
new file mode 100644
index 0000000..4bf9757
--- /dev/null
+++ b/src/chromite/api/firmware.proto
@@ -0,0 +1,127 @@
+syntax = "proto3";
+package chromite.api;
+
+option go_package = "go.chromium.org/chromiumos/infra/proto/go/chromite/api";
+
+import "chromite/api/build_api.proto";
+
+// Protos for executing firmware builder functionality.
+
+// List of known location that firmware can be built from
+enum FwLocation {
+  FW_LOCATION_UNKNOWN = 0;
+  PLATFORM_EC = 1; // platform/ec/firmware_builder.py
+  PLATFORM_ZEPHYR = 2; // platform/zephyr-chrome/firmware_builder.py
+}
+
+// Metrics collected on every successful firmware build
+message FwBuildMetric {
+  // Lowercase name of the firmware target built. E.g. phaser
+  string target_name = 1;
+
+  // Lowercase name of the platform the firmware target belongs to. May be
+  // blank. E.g. octopus
+  string platform_name = 2;
+
+  // List of firmware sections and their free and total sizes in bytes
+  repeated FwSection fw_section = 3;
+
+  message FwSection {
+    // Region as described in FMAP or linker script.
+    // E.g. EC_RO, EC_RW, EC_NVRAM, RO_BSS, RW_BSS, SHARED_MEM
+    FwRegion region = 1;
+
+    enum FwRegion {
+      FW_REGION_UNKNOWN = 0;
+      EC_RO = 1;  // The entire section protected by write protect
+      EC_RW = 2;  // Also RW_A for EFS1 systems
+      EC_RO_BSS = 3;
+      EC_RW_BSS = 4;
+      EC_SHARED_MEM = 5;
+    }
+
+    // The number of bytes used in this section
+    uint32 used = 2;
+
+    // The total number of bytes available in this section
+    uint32 total = 3;
+  }
+
+  // Version number components: "major.minor.tiny".
+  message Version {
+    uint32 major = 1;
+    uint32 minor = 2;
+    uint32 tiny = 3;
+  }
+
+  // Optional information related to a specific target type
+  oneof image_type {
+    ZephyrTarget zephyr = 4;
+  }
+
+  // Zephyr-base firmware target related build metrics
+  message ZephyrTarget {
+    // The version of the Zephyr kernel used during build
+    Version kernel_version = 1;
+  }
+}
+
+// A list of FW metrics collected on every successful firmware build
+// Implementation note, this is a separate message since it serves as the
+// serialization base between the build_api end point and the entry point
+// in the firmware_builder.py
+message FwBuildMetricList {
+  repeated FwBuildMetric value = 1;
+}
+
+// Metrics collect on successful firmware unit test runs
+message FwTestMetric {
+  // Name of firmware test
+  string name = 1;
+}
+
+// A list of FW metrics collected on every successful firmware unit test.
+// Implementation note, this is a separate message since it serves as the
+// serialization base between the build_api end point and the entry point
+// in the firmware_builder.py
+message FwTestMetricList {
+  repeated FwTestMetric value = 1;
+}
+
+message BuildAllTotFirmwareRequest {
+  // Location of firmware to build call into firmware_builder.py entry point.
+  // The `build` subcommand will be called
+  FwLocation firmware_location = 1;
+}
+
+message BuildAllTotFirmwareResponse {
+  // Metrics collected on every successful firmware build
+  FwBuildMetricList metrics = 1;
+}
+
+message TestAllTotFirmwareRequest {
+  // Location of firmware to build call into firmware_builder.py entry point.
+  // The `test` subcommand will be called
+  FwLocation firmware_location = 1;
+}
+
+message TestAllTotFirmwareResponse {
+  // Metrics collect on successfuly firmware unit test runs
+  FwTestMetricList metrics = 1;
+}
+
+// The Firmware service.
+service FirmwareService {
+  option (service_options) = {
+    module: "firmware",
+    service_chroot_assert: INSIDE,
+  };
+
+  // Builds all of the firmware targets on ToT at specified location
+  rpc BuildAllTotFirmware(BuildAllTotFirmwareRequest)
+      returns (BuildAllTotFirmwareResponse);
+
+  // Runs all of the firmware tests on ToT at specified location
+  rpc TestAllTotFirmware(TestAllTotFirmwareRequest)
+      returns (TestAllTotFirmwareResponse);
+}