Identifier

This commit is contained in:
Sebastien Bourdeauducq 2012-05-17 01:41:41 +02:00
parent 141269b384
commit 79124d822b
8 changed files with 112 additions and 115 deletions

View file

@ -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)

View file

@ -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) {

View file

@ -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 */

31
software/include/hw/id.h Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef __HW_ID_H
#define __HW_ID_H
#include <hw/common.h>
#include <csrbase.h>
#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 */

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef __HW_SYSCTL_H
#define __HW_SYSCTL_H
#include <hw/common.h>
#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 */

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <hw/sysctl.h>
#include <hw/id.h>
#include <hw/gpio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <version.h>
#include <board.h>
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");
}

View file

@ -17,7 +17,6 @@
#include <irq.h>
#include <uart.h>
#include <hw/sysctl.h>
#include <system.h>
@ -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);
}

8
top.py
View file

@ -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
])
#