Plumb git commit hash into ROM

Related to #199
diff --git a/sw/boot_rom/Makefile b/sw/boot_rom/Makefile
index b938b61..c5dd590 100644
--- a/sw/boot_rom/Makefile
+++ b/sw/boot_rom/Makefile
@@ -6,9 +6,10 @@
 
 NAME          = boot_rom
 SRCS          = bootstrap.c boot_rom.c
-LINKER_SCRIPT = link.ld
+LINKER_SCRIPT = rom_link.ld
 CRT_SRCS      =
 EXT_ASMS      = crt0.S
+CHIP_INFO     = chip_info.h
 
 PROGRAM_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
 SW_DIR      := $(PROGRAM_DIR)/..
diff --git a/sw/boot_rom/boot_rom.c b/sw/boot_rom/boot_rom.c
index 3b144a4..89e8662 100644
--- a/sw/boot_rom/boot_rom.c
+++ b/sw/boot_rom/boot_rom.c
@@ -8,6 +8,7 @@
 #include "gpio.h"
 #include "spi_device.h"
 #include "uart.h"
+#include "chip_info.h"
 
 static inline void try_launch(void) {
   __asm__ volatile(
@@ -21,6 +22,7 @@
 
 int main(int argc, char **argv) {
   uart_init(UART_BAUD_RATE);
+  uart_send_str((char *)chip_info);
 
   int rv = bootstrap();
   if (rv) {
diff --git a/sw/boot_rom/rom_link.ld b/sw/boot_rom/rom_link.ld
index 57d96ca..c8fd0b5 100644
--- a/sw/boot_rom/rom_link.ld
+++ b/sw/boot_rom/rom_link.ld
@@ -8,9 +8,9 @@
 
 MEMORY
 {
-    rom (rx)   : ORIGIN = 0x00008000, LENGTH = 0x2000
-    ram (w)    : ORIGIN = 0x10000000, LENGTH = 0x10000
-    flash (rx) : ORIGIN = 0x20000000, LENGTH = 0x100000
+    rom (rx)     : ORIGIN = 0x00008000, LENGTH = 0x2000
+    ram (w)      : ORIGIN = 0x10000000, LENGTH = 0x10000
+    flash (rx)   : ORIGIN = 0x20000000, LENGTH = 0x100000
 }
 
 /* Memory Allocation */
@@ -18,6 +18,8 @@
 _stack_size = 0x2000;
 _stack_start = ORIGIN(ram) + _heap_size + _stack_size;
 _flash_start = ORIGIN(flash);
+_chip_info_size = 128;
+_chip_info_start = ORIGIN(rom) + LENGTH(rom) - _chip_info_size;
 
 /* We have to align each sector to word boundaries as our current s19->slm
  * conversion scripts are not able to handle non-word aligned sections. */
@@ -72,6 +74,11 @@
         _edata  =  .;
     } > rom
 
+    .chip_info _chip_info_start : {
+        . = ALIGN(4);
+        *(.chip_info)
+    } > rom
+
     .bss :
     {
         . = ALIGN(4);
diff --git a/sw/exts/common/common.mk b/sw/exts/common/common.mk
index 4f9b3b7..e1c70ed 100644
--- a/sw/exts/common/common.mk
+++ b/sw/exts/common/common.mk
@@ -32,12 +32,15 @@
 %.bin: %.elf
 	$(OBJCOPY) -O binary $^ $@
 
-%.o: %.c
+%.o: %.c $(CHIP_INFO)
 	$(CC) $(CFLAGS) -MMD -c $(INCS) -o $@ $<
 
 %.o: %.S
 	$(CC) $(CFLAGS) -MMD -c $(INCS) -o $@ $<
 
+$(CHIP_INFO):
+	$(RM) chip_info.h
+	$(INFOTOOL) -o $(shell pwd)
 
 -include $(DEPS)
 
diff --git a/sw/exts/common/options.mk b/sw/exts/common/options.mk
index 10fb91a..7133fec 100644
--- a/sw/exts/common/options.mk
+++ b/sw/exts/common/options.mk
@@ -23,6 +23,7 @@
 CRT_SRCS      ?= $(EXT_DIR)/_crt.c
 EXT_SRCS      ?= $(CRT_SRCS)
 EXT_ASMS      ?=
+CHIP_INFO     ?=
 VENDOR_DIR    := $(SW_DIR)/vendor
 
 RV_TOOLS      ?= /tools/riscv/bin/
@@ -34,6 +35,7 @@
 LINKER_SCRIPT ?= $(EXT_DIR)/link.ld
 
 REGTOOL        = $(ROOT_DIR)/util/regtool.py
+INFOTOOL       = $(ROOT_DIR)/util/rom_chip_info.py
 
 CC            := $(RV_TOOLS)/riscv32-unknown-elf-gcc
 CFLAGS        ?= -Wall -g -Os -march=$(ARCH) -mabi=ilp32 -static -mcmodel=medany \
@@ -46,3 +48,4 @@
 INCS          +=-I$(LIB_DIR) -I$(VENDOR_DIR)
 
 OUTFILES      := $(EXE).elf $(EXE).vmem $(EXE).bin $(EXE).dis $(EXE).map
+OUTFILES      += $(CHIP_INFO)
diff --git a/util/rom_chip_info.py b/util/rom_chip_info.py
new file mode 100755
index 0000000..3a4c180
--- /dev/null
+++ b/util/rom_chip_info.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+r"""Generates chip_info.h for ROM build
+"""
+
+import argparse
+import logging as log
+import os
+import sys
+from datetime import datetime
+from git import Repo
+from io import StringIO
+from pathlib import Path
+
+
+# Common header for generated files
+gentpl = r"""
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// ------------------- W A R N I N G: A U T O - G E N E R A T E D   C O D E !! -------------------//
+
+#ifndef _F_CHIPINFO_H__
+#define _F_CHIPINFO_H__
+
+static const char chip_info[128] __attribute__((section(".chip_info"))) =
+  "Commit ID:  {%commit_hash%}\r\n"
+  "Build Date: {%build_date%}\r\n";
+
+#endif
+
+"""
+def main():
+    parser = argparse.ArgumentParser(prog="rom_chip_info")
+    parser.add_argument('--outdir',
+                        '-o',
+                        required=True,
+                        help='Output Directory'
+                        )
+
+    log.basicConfig(format="%(levelname)s: %(message)s")
+    args = parser.parse_args()
+
+    if not args.outdir:
+        log.error("'--outdir' not specified")
+        raise SystemExit(sys.exc_info()[1])
+    else:
+        outdir = Path(args.outdir)
+
+    out_path = outdir / "chip_info.h"
+
+
+    repo = Repo(search_parent_directories=True)
+    repo_info = repo.head.object.hexsha
+
+    now = datetime.now()
+    wall_time = now.strftime("%Y-%m-%d, %H:%M:%S")
+
+    log.info("Info %s" % repo_info)
+    log.info("Time %s" % wall_time)
+
+    output = gentpl.replace('{%commit_hash%}', repo_info, 1)
+    output = output.replace('{%build_date%}', wall_time, 1)
+
+    with out_path.open(mode='w', encoding='UTF-8') as fout:
+        fout.write(output + "\n")
+
+
+if __name__ == "__main__":
+    main()