From 79124d822bc3d191bf8cc1ad82bbdf7989de0a74 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 17 May 2012 01:41:41 +0200 Subject: [PATCH] Identifier --- milkymist/identifier/__init__.py | 32 +++++++++++++++++++ software/bios/main.c | 3 +- software/include/base/board.h | 5 +-- software/include/hw/id.h | 31 ++++++++++++++++++ software/include/hw/sysctl.h | 55 -------------------------------- software/libbase/board.c | 51 ++++++++++++++++++++++------- software/libbase/system.c | 42 ------------------------ top.py | 8 +++-- 8 files changed, 112 insertions(+), 115 deletions(-) create mode 100644 milkymist/identifier/__init__.py create mode 100644 software/include/hw/id.h delete mode 100644 software/include/hw/sysctl.h diff --git a/milkymist/identifier/__init__.py b/milkymist/identifier/__init__.py new file mode 100644 index 00000000..38002252 --- /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 7225b35e..4d1eaafe 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 3227314c..02b23cf6 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 00000000..48c928ea --- /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 d00471b2..00000000 --- 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 b81779ef..b8adcfe9 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 b253c214..c39d2561 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 a756cdba..6d028bce 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 ]) # -- 2.30.2