2023-07-29 01:56:19 -04:00
|
|
|
// Test program for lcpu
|
2023-07-25 06:46:52 -04:00
|
|
|
#include <stdarg.h>
|
2023-07-27 06:03:28 -04:00
|
|
|
#include <stdint.h>
|
2023-07-25 06:46:52 -04:00
|
|
|
|
2023-07-29 01:56:19 -04:00
|
|
|
// MMIO types
|
|
|
|
|
|
|
|
/// This structure is at WIRE_BASE
|
|
|
|
typedef struct {
|
|
|
|
uint32_t nrInputs;
|
|
|
|
uint32_t nrOutputs;
|
|
|
|
} WireDevice_Header;
|
|
|
|
|
|
|
|
#define WIRE_BASE 0x11310000
|
|
|
|
#define WIRE_HEADER ((volatile WireDevice_Header*)WIRE_BASE)
|
|
|
|
#define WIRE_IO_BASE WIRE_BASE + sizeof(WireDevice_Header)
|
|
|
|
#define WIRE_OUTPUT_BASE WIRE_IO_BASE + (WIRE_HEADER->nrInputs * sizeof(uint32_t))
|
|
|
|
#define WIRE_INPUT(i) *(volatile const uint32_t*)(WIRE_IO_BASE + (i * sizeof(uint32_t)))
|
|
|
|
#define WIRE_OUTPUT(i) *(volatile uint32_t*)(WIRE_OUTPUT_BASE + (i * sizeof(uint32_t)))
|
|
|
|
|
|
|
|
#define SYSCON *(volatile uint32_t*)0x11100000
|
|
|
|
|
|
|
|
#define UART_BASE 0x10000000
|
|
|
|
#define UART_DATA *(volatile uint32_t*)UART_BASE
|
|
|
|
#define UART_STATUS UART_DATA
|
|
|
|
|
2023-07-25 06:46:52 -04:00
|
|
|
uint32_t strlen(const char* str) {
|
|
|
|
if(!str)
|
|
|
|
return 0;
|
|
|
|
const char* c = str;
|
|
|
|
while(*c++)
|
|
|
|
;
|
|
|
|
return c - str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void putc(char c) {
|
|
|
|
UART_DATA = (uint32_t)c;
|
|
|
|
}
|
|
|
|
|
|
|
|
__attribute__((noinline)) void puts(const char* str) {
|
|
|
|
const uint32_t length = strlen(str);
|
|
|
|
for(uint32_t i = 0; i < length; ++i)
|
|
|
|
putc(str[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
int itoa(int value, char* sp, int radix) {
|
|
|
|
char tmp[16];
|
|
|
|
char* tp = tmp;
|
|
|
|
int i;
|
|
|
|
unsigned v;
|
|
|
|
|
|
|
|
int sign = (radix == 10 && value < 0);
|
|
|
|
if(sign)
|
|
|
|
v = -value;
|
|
|
|
else
|
|
|
|
v = (unsigned)value;
|
|
|
|
|
|
|
|
while(v || tp == tmp) {
|
|
|
|
i = v % radix;
|
|
|
|
v /= radix;
|
|
|
|
if(i < 10)
|
|
|
|
*tp++ = i + '0';
|
|
|
|
else
|
|
|
|
*tp++ = i + 'a' - 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
int len = tp - tmp;
|
|
|
|
|
|
|
|
if(sign) {
|
|
|
|
*sp++ = '-';
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(tp > tmp)
|
|
|
|
*sp++ = *--tp;
|
|
|
|
|
|
|
|
*sp = '\0';
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
void vprintf(const char* format, va_list val) {
|
|
|
|
const int fl = strlen(format);
|
|
|
|
for(int i = 0; i < fl; ++i) {
|
|
|
|
switch(format[i]) {
|
|
|
|
case '%':
|
2023-07-27 06:03:28 -04:00
|
|
|
if(format[i + 1] == '%')
|
2023-07-25 06:46:52 -04:00
|
|
|
putc('%');
|
2023-07-27 06:03:28 -04:00
|
|
|
switch(format[i + 1]) {
|
2023-07-25 06:46:52 -04:00
|
|
|
case 'i':
|
|
|
|
case 'd': {
|
|
|
|
char a[32];
|
|
|
|
itoa(va_arg(val, uint32_t), &a[0], 10);
|
|
|
|
|
|
|
|
const int al = strlen(a);
|
|
|
|
for(int j = 0; j < al; ++j)
|
|
|
|
putc(a[j]);
|
2023-07-27 06:03:28 -04:00
|
|
|
i++;
|
2023-07-25 06:46:52 -04:00
|
|
|
} break;
|
|
|
|
|
|
|
|
case 's': {
|
|
|
|
char* p = va_arg(val, char*);
|
|
|
|
if(!p)
|
|
|
|
puts("(null)");
|
|
|
|
else
|
|
|
|
puts(p);
|
2023-07-27 06:03:28 -04:00
|
|
|
i++;
|
2023-07-25 06:46:52 -04:00
|
|
|
};
|
|
|
|
|
2023-07-27 06:03:28 -04:00
|
|
|
default: putc(' '); break;
|
2023-07-25 06:46:52 -04:00
|
|
|
}
|
2023-07-27 06:03:28 -04:00
|
|
|
break;
|
2023-07-28 06:05:58 -04:00
|
|
|
case '\0': // band-aid fix.
|
|
|
|
return;
|
2023-07-27 06:03:28 -04:00
|
|
|
default: putc(format[i]); break;
|
2023-07-25 06:46:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void printf(const char* format, ...) {
|
|
|
|
va_list val;
|
|
|
|
va_start(val, format);
|
2023-07-27 06:03:28 -04:00
|
|
|
vprintf(format, val);
|
2023-07-25 06:46:52 -04:00
|
|
|
va_end(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
void main() {
|
2023-07-29 01:56:19 -04:00
|
|
|
printf("Wire interface: %d inputs, %d outputs\n", WIRE_HEADER->nrInputs, WIRE_HEADER->nrOutputs);
|
2023-07-27 06:03:28 -04:00
|
|
|
|
2023-07-29 01:56:19 -04:00
|
|
|
for(uint32_t i = 0; i < WIRE_HEADER->nrInputs; ++i)
|
|
|
|
printf("Wire input %d: value %d\n", i, WIRE_INPUT(i));
|
2023-07-27 06:03:28 -04:00
|
|
|
|
2023-07-29 01:56:19 -04:00
|
|
|
for(uint32_t i = 0; i < WIRE_HEADER->nrOutputs; ++i) {
|
|
|
|
printf("Setting wire output %d\n", i);
|
|
|
|
WIRE_OUTPUT(i) = 10 + i;
|
|
|
|
}
|
2023-07-25 06:46:52 -04:00
|
|
|
|
2023-07-29 01:56:19 -04:00
|
|
|
#if 1
|
|
|
|
for(;;)
|
|
|
|
;
|
|
|
|
__builtin_unreachable();
|
|
|
|
#else
|
2023-07-25 06:46:52 -04:00
|
|
|
SYSCON = 0x5555;
|
2023-07-29 01:56:19 -04:00
|
|
|
#endif
|
2023-07-25 06:46:52 -04:00
|
|
|
}
|