mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-05-17 12:12:35 +00:00
This comes in two parts: - A generator script which uses LiteX to generate litedram cores along with their init files for various boards (currently Arty and Nexys-video). This comes with configs for arty and nexys_video. - A fusesoc "generator" which uses pre-generated litedram cores The generation process is manual on purpose. This include pre-generated cores for the two above boards. This is done so that one doesn't have to install LiteX to build microwatt. In addition, the generator script or wrapper vhdl tend to break when LiteX changes significantly which happens. This is still rather standalone and hasn't been plumbed into the SoC or the FPGA toplevel files yet. At this point LiteDRAM self-initializes using a built-in VexRiscv "Minimum" core obtained from LiteX and included in this commit. There is some plumbing to generate and cores that are initialized by Microwatt directly but this isn't working yet and so isn't enabled yet. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
305 lines
6.4 KiB
C
305 lines
6.4 KiB
C
/******************************************************************************
|
|
* Copyright (c) 2004, 2008 IBM Corporation
|
|
* All rights reserved.
|
|
* This program and the accompanying materials
|
|
* are made available under the terms of the BSD License
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.opensource.org/licenses/bsd-license.php
|
|
*
|
|
* Contributors:
|
|
* IBM Corporation - initial implementation
|
|
*****************************************************************************/
|
|
|
|
#include <stdbool.h>
|
|
#include <compiler.h>
|
|
#include "stdio.h"
|
|
#include "stdlib.h"
|
|
#include "string.h"
|
|
#include "ctype.h"
|
|
#include <stdarg.h>
|
|
|
|
static const unsigned long long convert[] = {
|
|
0x0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF,
|
|
0xFFFFFFFFFFULL, 0xFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
|
|
};
|
|
|
|
static int
|
|
print_str_fill(char **buffer, size_t bufsize, char *sizec,
|
|
const char *str, char c)
|
|
{
|
|
size_t i, sizei, len;
|
|
char *bstart = *buffer;
|
|
|
|
sizei = strtoul(sizec, NULL, 10);
|
|
len = strlen(str);
|
|
if (sizei > len) {
|
|
for (i = 0;
|
|
(i < (sizei - len)) && ((*buffer - bstart) < bufsize);
|
|
i++) {
|
|
**buffer = c;
|
|
*buffer += 1;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
print_str(char **buffer, size_t bufsize, const char *str)
|
|
{
|
|
char *bstart = *buffer;
|
|
size_t i;
|
|
|
|
for (i = 0; (i < strlen(str)) && ((*buffer - bstart) < bufsize); i++) {
|
|
**buffer = str[i];
|
|
*buffer += 1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static unsigned int __attrconst
|
|
print_intlen(unsigned long value, unsigned short int base)
|
|
{
|
|
int i = 0;
|
|
|
|
while (value > 0) {
|
|
if (base == 16)
|
|
value >>= 4;
|
|
else
|
|
value /= base;
|
|
i++;
|
|
}
|
|
if (i == 0)
|
|
i = 1;
|
|
return i;
|
|
}
|
|
|
|
static int
|
|
print_itoa(char **buffer, size_t bufsize, unsigned long value,
|
|
unsigned short base, bool upper)
|
|
{
|
|
const char zeichen[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
|
char c;
|
|
int i, len;
|
|
|
|
if(base <= 2 || base > 16)
|
|
return 0;
|
|
|
|
len = i = print_intlen(value, base);
|
|
|
|
/* Don't print to buffer if bufsize is not enough. */
|
|
if (len > bufsize)
|
|
return 0;
|
|
|
|
do {
|
|
c = zeichen[value % base];
|
|
if (upper)
|
|
c = toupper(c);
|
|
|
|
(*buffer)[--i] = c;
|
|
value /= base;
|
|
} while(value);
|
|
|
|
*buffer += len;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
print_fill(char **buffer, size_t bufsize, char *sizec, unsigned long size,
|
|
unsigned short int base, char c, int optlen)
|
|
{
|
|
int i, sizei, len;
|
|
char *bstart = *buffer;
|
|
|
|
sizei = strtoul(sizec, NULL, 10);
|
|
len = print_intlen(size, base) + optlen;
|
|
if (sizei > len) {
|
|
for (i = 0;
|
|
(i < (sizei - len)) && ((*buffer - bstart) < bufsize);
|
|
i++) {
|
|
**buffer = c;
|
|
*buffer += 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int
|
|
print_format(char **buffer, size_t bufsize, const char *format, void *var)
|
|
{
|
|
char *start;
|
|
unsigned int i = 0, length_mod = sizeof(int);
|
|
unsigned long value = 0;
|
|
unsigned long signBit;
|
|
char *form, sizec[32];
|
|
char sign = ' ';
|
|
bool upper = false;
|
|
|
|
form = (char *) format;
|
|
start = *buffer;
|
|
|
|
form++;
|
|
if(*form == '0' || *form == '.') {
|
|
sign = '0';
|
|
form++;
|
|
}
|
|
|
|
while ((*form != '\0') && ((*buffer - start) < bufsize)) {
|
|
switch(*form) {
|
|
case 'u':
|
|
case 'd':
|
|
case 'i':
|
|
sizec[i] = '\0';
|
|
value = (unsigned long) var;
|
|
signBit = 0x1ULL << (length_mod * 8 - 1);
|
|
if ((*form != 'u') && (signBit & value)) {
|
|
**buffer = '-';
|
|
*buffer += 1;
|
|
value = (-(unsigned long)value) & convert[length_mod];
|
|
}
|
|
print_fill(buffer, bufsize - (*buffer - start),
|
|
sizec, value, 10, sign, 0);
|
|
print_itoa(buffer, bufsize - (*buffer - start),
|
|
value, 10, upper);
|
|
break;
|
|
case 'X':
|
|
upper = true;
|
|
/* fallthrough */
|
|
case 'x':
|
|
sizec[i] = '\0';
|
|
value = (unsigned long) var & convert[length_mod];
|
|
print_fill(buffer, bufsize - (*buffer - start),
|
|
sizec, value, 16, sign, 0);
|
|
print_itoa(buffer, bufsize - (*buffer - start),
|
|
value, 16, upper);
|
|
break;
|
|
case 'O':
|
|
case 'o':
|
|
sizec[i] = '\0';
|
|
value = (long int) var & convert[length_mod];
|
|
print_fill(buffer, bufsize - (*buffer - start),
|
|
sizec, value, 8, sign, 0);
|
|
print_itoa(buffer, bufsize - (*buffer - start),
|
|
value, 8, upper);
|
|
break;
|
|
case 'p':
|
|
sizec[i] = '\0';
|
|
print_fill(buffer, bufsize - (*buffer - start),
|
|
sizec, (unsigned long) var, 16, ' ', 2);
|
|
print_str(buffer, bufsize - (*buffer - start),
|
|
"0x");
|
|
print_itoa(buffer, bufsize - (*buffer - start),
|
|
(unsigned long) var, 16, upper);
|
|
break;
|
|
case 'c':
|
|
sizec[i] = '\0';
|
|
print_fill(buffer, bufsize - (*buffer - start),
|
|
sizec, 1, 10, ' ', 0);
|
|
**buffer = (unsigned long) var;
|
|
*buffer += 1;
|
|
break;
|
|
case 's':
|
|
sizec[i] = '\0';
|
|
print_str_fill(buffer,
|
|
bufsize - (*buffer - start), sizec,
|
|
(char *) var, ' ');
|
|
|
|
print_str(buffer, bufsize - (*buffer - start),
|
|
(char *) var);
|
|
break;
|
|
case 'l':
|
|
form++;
|
|
if(*form == 'l') {
|
|
length_mod = sizeof(long long int);
|
|
} else {
|
|
form--;
|
|
length_mod = sizeof(long int);
|
|
}
|
|
break;
|
|
case 'h':
|
|
form++;
|
|
if(*form == 'h') {
|
|
length_mod = sizeof(signed char);
|
|
} else {
|
|
form--;
|
|
length_mod = sizeof(short int);
|
|
}
|
|
break;
|
|
case 'z':
|
|
length_mod = sizeof(size_t);
|
|
break;
|
|
default:
|
|
if(*form >= '0' && *form <= '9')
|
|
sizec[i++] = *form;
|
|
}
|
|
form++;
|
|
}
|
|
|
|
|
|
return (long int) (*buffer - start);
|
|
}
|
|
|
|
|
|
/*
|
|
* The vsnprintf function prints a formatted strings into a buffer.
|
|
* BUG: buffer size checking does not fully work yet
|
|
*/
|
|
int
|
|
vsnprintf(char *buffer, size_t bufsize, const char *format, va_list arg)
|
|
{
|
|
char *ptr, *bstart;
|
|
|
|
bstart = buffer;
|
|
ptr = (char *) format;
|
|
|
|
/*
|
|
* Return from here if size passed is zero, otherwise we would
|
|
* overrun buffer while setting NULL character at the end.
|
|
*/
|
|
if (!buffer || !bufsize)
|
|
return 0;
|
|
|
|
/* Leave one space for NULL character */
|
|
bufsize--;
|
|
|
|
while(*ptr != '\0' && (buffer - bstart) < bufsize)
|
|
{
|
|
if(*ptr == '%') {
|
|
char formstr[20];
|
|
int i=0;
|
|
|
|
do {
|
|
formstr[i] = *ptr;
|
|
ptr++;
|
|
i++;
|
|
} while(!(*ptr == 'd' || *ptr == 'i' || *ptr == 'u' || *ptr == 'x' || *ptr == 'X'
|
|
|| *ptr == 'p' || *ptr == 'c' || *ptr == 's' || *ptr == '%'
|
|
|| *ptr == 'O' || *ptr == 'o' ));
|
|
formstr[i++] = *ptr;
|
|
formstr[i] = '\0';
|
|
if(*ptr == '%') {
|
|
*buffer++ = '%';
|
|
} else {
|
|
print_format(&buffer,
|
|
bufsize - (buffer - bstart),
|
|
formstr, va_arg(arg, void *));
|
|
}
|
|
ptr++;
|
|
} else {
|
|
|
|
*buffer = *ptr;
|
|
|
|
buffer++;
|
|
ptr++;
|
|
}
|
|
}
|
|
|
|
*buffer = '\0';
|
|
|
|
return (buffer - bstart);
|
|
}
|