mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Identifier
This commit is contained in:
parent
141269b384
commit
79124d822b
8 changed files with 112 additions and 115 deletions
32
milkymist/identifier/__init__.py
Normal file
32
milkymist/identifier/__init__.py
Normal 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)
|
|
@ -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) {
|
||||
|
|
|
@ -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
31
software/include/hw/id.h
Normal 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 */
|
|
@ -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 */
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
8
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
|
||||
])
|
||||
|
||||
#
|
||||
|
|
Loading…
Reference in a new issue