diff --git a/milkymist/identifier/__init__.py b/milkymist/identifier/__init__.py
new file mode 100644
index 000000000..380022520
--- /dev/null
+++ b/milkymist/identifier/__init__.py
@@ -0,0 +1,32 @@
+from migen.fhdl.structure import *
+from migen.bank.description import *
+from migen.bank import csrgen
+
+import re
+
+def encode_version(version):
+ match = re.match("(\d+)\.(\d+)(\.(\d+))?(rc(\d+))?", version, re.IGNORECASE)
+ r = (int(match.group(1)) << 12) | (int(match.group(2)) << 8)
+ subminor = match.group(4)
+ rc = match.group(6)
+ if subminor:
+ r |= int(subminor) << 4
+ if rc:
+ r |= int(rc)
+ return r
+
+class Identifier:
+ def __init__(self, address, sysid, version):
+ self.sysid = sysid
+ self.version = encode_version(version)
+
+ self._r_sysid = RegisterField("sysid", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+ self._r_version = RegisterField("version", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
+ self.bank = csrgen.Bank([self._r_sysid, self._r_version], address=address)
+
+ def get_fragment(self):
+ comb = [
+ self._r_sysid.field.w.eq(self.sysid),
+ self._r_version.field.w.eq(self.version)
+ ]
+ return self.bank.get_fragment() + Fragment(comb)
diff --git a/software/bios/main.c b/software/bios/main.c
index 7225b35e2..4d1eaafe7 100644
--- a/software/bios/main.c
+++ b/software/bios/main.c
@@ -344,8 +344,6 @@ static void do_command(char *c)
else if(strcmp(token, "crc") == 0) crc(get_token(&c), get_token(&c));
else if(strcmp(token, "version") == 0) puts(VERSION);
- else if(strcmp(token, "reboot") == 0) reboot();
- else if(strcmp(token, "reconf") == 0) reconf();
else if(strcmp(token, "help") == 0) help();
@@ -453,6 +451,7 @@ int main(int i, char **c)
crcbios();
if(rescue)
printf("Rescue mode\n");
+ board_init();
print_mac();
ddr_ok = ddrinit();
if(ddr_ok) {
diff --git a/software/include/base/board.h b/software/include/base/board.h
index 3227314ca..02b23cf6d 100644
--- a/software/include/base/board.h
+++ b/software/include/base/board.h
@@ -26,10 +26,11 @@ struct board_desc {
unsigned int ethernet_phyadr;
};
-const struct board_desc *get_board_desc_id(unsigned short int id);
-const struct board_desc *get_board_desc(void);
int get_pcb_revision(void);
void get_soc_version(unsigned int *major, unsigned int *minor, unsigned int *subminor, unsigned int *rc);
void get_soc_version_formatted(char *version);
+extern const struct board_desc *brd_desc;
+void board_init(void);
+
#endif /* __BOARD_H */
diff --git a/software/include/hw/id.h b/software/include/hw/id.h
new file mode 100644
index 000000000..48c928ea5
--- /dev/null
+++ b/software/include/hw/id.h
@@ -0,0 +1,31 @@
+/*
+ * Milkymist SoC (Software)
+ * Copyright (C) 2007, 2008, 2009, 2010, 2012 Sebastien Bourdeauducq
+ *
+ * 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 Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __HW_ID_H
+#define __HW_ID_H
+
+#include
+#include
+
+#define ID_CSR(x) MMPTR(ID_BASE+(x))
+
+#define CSR_ID_SYSTEMH ID_CSR(0x00)
+#define CSR_ID_SYSTEML ID_CSR(0x04)
+#define CSR_ID_VERSIONH ID_CSR(0x08)
+#define CSR_ID_VERSIONL ID_CSR(0x0c)
+
+#endif /* __HW_ID_H */
diff --git a/software/include/hw/sysctl.h b/software/include/hw/sysctl.h
deleted file mode 100644
index d00471b2a..000000000
--- a/software/include/hw/sysctl.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Milkymist SoC (Software)
- * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
- *
- * 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 Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#ifndef __HW_SYSCTL_H
-#define __HW_SYSCTL_H
-
-#include
-
-#define CSR_GPIO_IN MMPTR(0xe0001000)
-#define CSR_GPIO_OUT MMPTR(0xe0001004)
-#define CSR_GPIO_INTEN MMPTR(0xe0001008)
-
-#define CSR_TIMER0_CONTROL MMPTR(0xe0001010)
-#define CSR_TIMER0_COMPARE MMPTR(0xe0001014)
-#define CSR_TIMER0_COUNTER MMPTR(0xe0001018)
-
-#define CSR_TIMER1_CONTROL MMPTR(0xe0001020)
-#define CSR_TIMER1_COMPARE MMPTR(0xe0001024)
-#define CSR_TIMER1_COUNTER MMPTR(0xe0001028)
-
-#define TIMER_ENABLE (0x01)
-#define TIMER_AUTORESTART (0x02)
-
-#define CSR_ICAP MMPTR(0xe0001040)
-
-#define ICAP_READY (0x01)
-
-#define ICAP_CE (0x10000)
-#define ICAP_WRITE (0x20000)
-
-#define CSR_DBG_SCRATCHPAD MMPTR(0xe0001050)
-#define CSR_DBG_CTRL MMPTR(0xe0001054)
-
-#define DBG_CTRL_GDB_ROM_LOCK (0x01)
-#define DBG_CTRL_BUS_ERR_EN (0x02)
-
-#define CSR_FREQUENCY MMPTR(0xe0001074)
-#define CSR_CAPABILITIES MMPTR(0xe0001078)
-#define CSR_SYSTEM_ID MMPTR(0xe000107c)
-
-#endif /* __HW_SYSCTL_H */
diff --git a/software/libbase/board.c b/software/libbase/board.c
index b81779ef6..b8adcfe96 100644
--- a/software/libbase/board.c
+++ b/software/libbase/board.c
@@ -1,6 +1,6 @@
/*
* Milkymist SoC (Software)
- * Copyright (C) 2007, 2008, 2009, 2011 Sebastien Bourdeauducq
+ * Copyright (C) 2007, 2008, 2009, 2011, 2012 Sebastien Bourdeauducq
*
* 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
@@ -15,10 +15,12 @@
* along with this program. If not, see .
*/
-#include
+#include
#include
#include
#include
+#include
+#include
#include
static const struct board_desc boards[1] = {
@@ -29,7 +31,7 @@ static const struct board_desc boards[1] = {
},
};
-const struct board_desc *get_board_desc_id(unsigned short int id)
+static const struct board_desc *get_board_desc_id(unsigned short int id)
{
unsigned int i;
@@ -39,18 +41,19 @@ const struct board_desc *get_board_desc_id(unsigned short int id)
return NULL;
}
-const struct board_desc *get_board_desc(void)
+static const struct board_desc *get_board_desc(void)
{
- return get_board_desc_id(CSR_SYSTEM_ID & 0xffff);
+ return get_board_desc_id((CSR_ID_SYSTEMH << 8) | CSR_ID_SYSTEML);
}
int get_pcb_revision(void)
{
+ /* TODO
int r;
unsigned int io;
- io = CSR_GPIO_IN;
r = 0;
+ io = CSR_GPIO_IN;
if(io & GPIO_PCBREV0)
r |= 0x1;
if(io & GPIO_PCBREV1)
@@ -59,18 +62,20 @@ int get_pcb_revision(void)
r |= 0x4;
if(io & GPIO_PCBREV3)
r |= 0x8;
- return r;
+ return r;*/
+ return 0;
}
void get_soc_version(unsigned int *major, unsigned int *minor, unsigned int *subminor, unsigned int *rc)
{
unsigned int id;
- id = CSR_SYSTEM_ID;
- *major = (id & 0xf0000000) >> 28;
- *minor = (id & 0x0f000000) >> 24;
- *subminor = (id & 0x00f00000) >> 20;
- *rc = (id & 0x000f0000) >> 16;
+ id = CSR_ID_VERSIONH;
+ *major = (id & 0xf0) >> 4;
+ *minor = id & 0x0f;
+ id = CSR_ID_VERSIONL;
+ *subminor = (id & 0xf0) >> 4;
+ *rc = id & 0x0f;
}
void get_soc_version_formatted(char *version)
@@ -85,3 +90,25 @@ void get_soc_version_formatted(char *version)
if(rc != 0)
sprintf(version, "RC%u", rc);
}
+
+const struct board_desc *brd_desc;
+
+void board_init(void)
+{
+ int rev;
+ char soc_version[13];
+
+ brd_desc = get_board_desc();
+
+ if(brd_desc == NULL) {
+ printf("Running on unknown board, startup aborted.\n");
+ while(1);
+ }
+ rev = get_pcb_revision();
+ get_soc_version_formatted(soc_version);
+ printf("Detected SoC %s on %s (PCB revision %d)\n", soc_version, brd_desc->name, rev);
+ if(strcmp(soc_version, VERSION) != 0)
+ printf("SoC and BIOS versions do not match!\n");
+ if(rev > 2)
+ printf("Unsupported PCB revision, please upgrade!\n");
+}
diff --git a/software/libbase/system.c b/software/libbase/system.c
index b253c2142..c39d25611 100644
--- a/software/libbase/system.c
+++ b/software/libbase/system.c
@@ -17,7 +17,6 @@
#include
#include
-#include
#include
@@ -39,44 +38,3 @@ void flush_cpu_dcache(void)
"nop\n"
);
}
-
-__attribute__((noreturn)) void reboot(void)
-{
- uart_sync();
- irq_setmask(0);
- irq_setie(0);
- CSR_SYSTEM_ID = 1; /* Writing to CSR_SYSTEM_ID causes a system reset */
- while(1);
-}
-
-static void icap_write(int val, unsigned int w)
-{
- while(!(CSR_ICAP & ICAP_READY));
- if(!val)
- w |= ICAP_CE|ICAP_WRITE;
- CSR_ICAP = w;
-}
-
-__attribute__((noreturn)) void reconf(void)
-{
- uart_sync();
- irq_setmask(0);
- irq_setie(0);
- icap_write(0, 0xffff); /* dummy word */
- icap_write(0, 0xffff); /* dummy word */
- icap_write(0, 0xffff); /* dummy word */
- icap_write(0, 0xffff); /* dummy word */
- icap_write(1, 0xaa99); /* sync word part 1 */
- icap_write(1, 0x5566); /* sync word part 2 */
- icap_write(1, 0x30a1); /* write to command register */
- icap_write(1, 0x0000); /* null command */
- icap_write(1, 0x30a1); /* write to command register */
- icap_write(1, 0x000e); /* reboot command */
- icap_write(1, 0x2000); /* NOP */
- icap_write(1, 0x2000); /* NOP */
- icap_write(1, 0x2000); /* NOP */
- icap_write(1, 0x2000); /* NOP */
- icap_write(0, 0x1111); /* NULL */
- icap_write(0, 0xffff); /* dummy word */
- while(1);
-}
diff --git a/top.py b/top.py
index a756cdba4..6d028bcef 100644
--- a/top.py
+++ b/top.py
@@ -5,7 +5,7 @@ from migen.fhdl.structure import *
from migen.fhdl import verilog, autofragment
from migen.bus import wishbone, wishbone2asmi, csr, wishbone2csr, dfi
-from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii, asmicon
+from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii, asmicon, identifier
from cmacros import get_macros
from constraints import Constraints
@@ -63,6 +63,8 @@ def csr_offset(name):
assert((base >= 0xe0000000) and (base <= 0xe0010000))
return (base - 0xe0000000)//0x800
+version = get_macros("common/version.h")["VERSION"][1:-1]
+
def get():
#
# ASMI
@@ -112,9 +114,11 @@ def get():
# CSR
#
uart0 = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
+ identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version)
csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
uart0.bank.interface,
- dfii0.bank.interface
+ dfii0.bank.interface,
+ identifier0.bank.interface
])
#