mirror of https://github.com/m-labs/artiq.git
soc/runtime: split main.c, add gcd64
This commit is contained in:
parent
4de670b370
commit
a579b105b6
|
@ -3,7 +3,7 @@ include $(MSCDIR)/software/common.mak
|
||||||
BOARD=papilio_pro
|
BOARD=papilio_pro
|
||||||
SERIAL=/dev/ttyUSB1
|
SERIAL=/dev/ttyUSB1
|
||||||
|
|
||||||
OBJECTS=isr.o elf_loader.o main.o
|
OBJECTS=isr.o elf_loader.o symbols.o corecom_serial.o gpio.o rtio.o dds.o main.o
|
||||||
|
|
||||||
all: runtime.bin
|
all: runtime.bin
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __CORECOM_H
|
||||||
|
#define __CORECOM_H
|
||||||
|
|
||||||
|
int ident_and_download_kernel(void *buffer, int maxlength);
|
||||||
|
int rpc(int rpc_num, int n_args, ...);
|
||||||
|
void kernel_finished(void);
|
||||||
|
|
||||||
|
#endif /* __CORECOM_H */
|
|
@ -0,0 +1,128 @@
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <crc.h>
|
||||||
|
#include <uart.h>
|
||||||
|
#include <generated/csr.h>
|
||||||
|
|
||||||
|
#include "corecom.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MSGTYPE_REQUEST_IDENT = 0x01,
|
||||||
|
MSGTYPE_LOAD_KERNEL = 0x02,
|
||||||
|
MSGTYPE_KERNEL_FINISHED = 0x03,
|
||||||
|
MSGTYPE_RPC_REQUEST = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int receive_int(void)
|
||||||
|
{
|
||||||
|
unsigned int r;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
r = 0;
|
||||||
|
for(i=0;i<4;i++) {
|
||||||
|
r <<= 8;
|
||||||
|
r |= (unsigned char)uart_read();
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char receive_char(void)
|
||||||
|
{
|
||||||
|
return uart_read();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_int(int x)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0;i<4;i++) {
|
||||||
|
uart_write((x & 0xff000000) >> 24);
|
||||||
|
x <<= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_sint(short int i)
|
||||||
|
{
|
||||||
|
uart_write((i >> 8) & 0xff);
|
||||||
|
uart_write(i & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_char(char c)
|
||||||
|
{
|
||||||
|
uart_write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void receive_sync(void)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
int recognized;
|
||||||
|
|
||||||
|
recognized = 0;
|
||||||
|
while(recognized < 4) {
|
||||||
|
c = uart_read();
|
||||||
|
if(c == 0x5a)
|
||||||
|
recognized++;
|
||||||
|
else
|
||||||
|
recognized = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_sync(void)
|
||||||
|
{
|
||||||
|
send_int(0x5a5a5a5a);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ident_and_download_kernel(void *buffer, int maxlength)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
unsigned int crc;
|
||||||
|
int i;
|
||||||
|
char msgtype;
|
||||||
|
unsigned char *_buffer = buffer;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
receive_sync();
|
||||||
|
msgtype = receive_char();
|
||||||
|
if(msgtype == MSGTYPE_REQUEST_IDENT) {
|
||||||
|
send_int(0x41524f52); /* "AROR" - ARTIQ runtime on OpenRISC */
|
||||||
|
send_int(1000000000000LL/identifier_frequency_read()); /* RTIO clock period in picoseconds */
|
||||||
|
} else if(msgtype == MSGTYPE_LOAD_KERNEL) {
|
||||||
|
length = receive_int();
|
||||||
|
if(length > maxlength) {
|
||||||
|
send_char(0x4c); /* Incorrect length */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
crc = receive_int();
|
||||||
|
for(i=0;i<length;i++)
|
||||||
|
_buffer[i] = receive_char();
|
||||||
|
if(crc32(buffer, length) != crc) {
|
||||||
|
send_char(0x43); /* CRC failed */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
send_char(0x4f); /* kernel reception OK */
|
||||||
|
return length;
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rpc(int rpc_num, int n_args, ...)
|
||||||
|
{
|
||||||
|
send_sync();
|
||||||
|
send_char(MSGTYPE_RPC_REQUEST);
|
||||||
|
send_sint(rpc_num);
|
||||||
|
send_char(n_args);
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, n_args);
|
||||||
|
while(n_args--)
|
||||||
|
send_int(va_arg(args, int));
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return receive_int();
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernel_finished(void)
|
||||||
|
{
|
||||||
|
send_sync();
|
||||||
|
send_char(MSGTYPE_KERNEL_FINISHED);
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include <hw/common.h>
|
||||||
|
|
||||||
|
#include "dds.h"
|
||||||
|
|
||||||
|
#define DDS_FTW0 0x0a
|
||||||
|
#define DDS_FTW1 0x0b
|
||||||
|
#define DDS_FTW2 0x0c
|
||||||
|
#define DDS_FTW3 0x0d
|
||||||
|
#define DDS_FUD 0x40
|
||||||
|
#define DDS_GPIO 0x41
|
||||||
|
|
||||||
|
#define DDS_READ(addr) \
|
||||||
|
MMPTR(0xb0000000 + (addr)*4)
|
||||||
|
|
||||||
|
#define DDS_WRITE(addr, data) \
|
||||||
|
MMPTR(0xb0000000 + (addr)*4) = data
|
||||||
|
|
||||||
|
void dds_init(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DDS_WRITE(DDS_GPIO, 1 << 7);
|
||||||
|
|
||||||
|
for(i=0;i<8;i++) {
|
||||||
|
DDS_WRITE(DDS_GPIO, i);
|
||||||
|
DDS_WRITE(0x00, 0x78);
|
||||||
|
DDS_WRITE(0x01, 0x00);
|
||||||
|
DDS_WRITE(0x02, 0x00);
|
||||||
|
DDS_WRITE(0x03, 0x00);
|
||||||
|
DDS_WRITE(DDS_FUD, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dds_program(int channel, int ftw)
|
||||||
|
{
|
||||||
|
DDS_WRITE(DDS_GPIO, channel);
|
||||||
|
DDS_WRITE(DDS_FTW0, ftw & 0xff);
|
||||||
|
DDS_WRITE(DDS_FTW1, (ftw >> 8) & 0xff);
|
||||||
|
DDS_WRITE(DDS_FTW2, (ftw >> 16) & 0xff);
|
||||||
|
DDS_WRITE(DDS_FTW3, (ftw >> 24) & 0xff);
|
||||||
|
DDS_WRITE(DDS_FUD, 0);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef __DDS_H
|
||||||
|
#define __DDS_H
|
||||||
|
|
||||||
|
void dds_init(void);
|
||||||
|
void dds_program(int channel, int ftw);
|
||||||
|
|
||||||
|
#endif /* __DDS_H */
|
|
@ -89,7 +89,7 @@ struct elf32_sym {
|
||||||
SANITIZE_OFFSET_SIZE(offset, sizeof(target_type)); \
|
SANITIZE_OFFSET_SIZE(offset, sizeof(target_type)); \
|
||||||
target = (target_type *)((char *)elf_data + offset)
|
target = (target_type *)((char *)elf_data + offset)
|
||||||
|
|
||||||
static void *find_symbol(const struct symbol *symbols, const char *name)
|
void *find_symbol(const struct symbol *symbols, const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ static int fixup(void *dest, int dest_length, struct elf32_rela *rela, void *tar
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_elf(const struct symbol *symbols, void *elf_data, int elf_length, void *dest, int dest_length)
|
int load_elf(symbol_resolver resolver, void *elf_data, int elf_length, void *dest, int dest_length)
|
||||||
{
|
{
|
||||||
struct elf32_ehdr *ehdr;
|
struct elf32_ehdr *ehdr;
|
||||||
struct elf32_shdr *strtable;
|
struct elf32_shdr *strtable;
|
||||||
|
@ -199,7 +199,7 @@ int load_elf(const struct symbol *symbols, void *elf_data, int elf_length, void
|
||||||
void *target;
|
void *target;
|
||||||
|
|
||||||
name = (char *)elf_data + strtaboff + sym->name;
|
name = (char *)elf_data + strtaboff + sym->name;
|
||||||
target = find_symbol(symbols, name);
|
target = resolver(name);
|
||||||
if(target == NULL) {
|
if(target == NULL) {
|
||||||
printf("Undefined symbol: %s\n", name);
|
printf("Undefined symbol: %s\n", name);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -6,6 +6,9 @@ struct symbol {
|
||||||
void *target;
|
void *target;
|
||||||
};
|
};
|
||||||
|
|
||||||
int load_elf(const struct symbol *symbols, void *elf_data, int elf_length, void *dest, int dest_length);
|
void *find_symbol(const struct symbol *symbols, const char *name);
|
||||||
|
|
||||||
|
typedef void * (*symbol_resolver)(const char *name);
|
||||||
|
int load_elf(symbol_resolver resolver, void *elf_data, int elf_length, void *dest, int dest_length);
|
||||||
|
|
||||||
#endif /* __ELF_LOADER_H */
|
#endif /* __ELF_LOADER_H */
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <generated/csr.h>
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
void gpio_set(int channel, int value)
|
||||||
|
{
|
||||||
|
static int csr_value;
|
||||||
|
|
||||||
|
if(value)
|
||||||
|
csr_value |= 1 << channel;
|
||||||
|
else
|
||||||
|
csr_value &= ~(1 << channel);
|
||||||
|
leds_out_write(csr_value);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef __GPIO_H
|
||||||
|
#define __GPIO_H
|
||||||
|
|
||||||
|
void gpio_set(int channel, int value);
|
||||||
|
|
||||||
|
#endif /* __GPIO_H */
|
|
@ -1,208 +1,13 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <crc.h>
|
|
||||||
|
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
#include <uart.h>
|
#include <uart.h>
|
||||||
#include <console.h>
|
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
#include <hw/common.h>
|
|
||||||
#include <generated/csr.h>
|
|
||||||
|
|
||||||
|
#include "corecom.h"
|
||||||
#include "elf_loader.h"
|
#include "elf_loader.h"
|
||||||
|
#include "symbols.h"
|
||||||
enum {
|
#include "rtio.h"
|
||||||
MSGTYPE_REQUEST_IDENT = 0x01,
|
#include "dds.h"
|
||||||
MSGTYPE_LOAD_KERNEL = 0x02,
|
|
||||||
MSGTYPE_KERNEL_FINISHED = 0x03,
|
|
||||||
MSGTYPE_RPC_REQUEST = 0x04,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int receive_int(void)
|
|
||||||
{
|
|
||||||
unsigned int r;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
for(i=0;i<4;i++) {
|
|
||||||
r <<= 8;
|
|
||||||
r |= (unsigned char)uart_read();
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char receive_char(void)
|
|
||||||
{
|
|
||||||
return uart_read();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_int(int x)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0;i<4;i++) {
|
|
||||||
uart_write((x & 0xff000000) >> 24);
|
|
||||||
x <<= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_sint(short int i)
|
|
||||||
{
|
|
||||||
uart_write((i >> 8) & 0xff);
|
|
||||||
uart_write(i & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_char(char c)
|
|
||||||
{
|
|
||||||
uart_write(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void receive_sync(void)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
int recognized;
|
|
||||||
|
|
||||||
recognized = 0;
|
|
||||||
while(recognized < 4) {
|
|
||||||
c = uart_read();
|
|
||||||
if(c == 0x5a)
|
|
||||||
recognized++;
|
|
||||||
else
|
|
||||||
recognized = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_sync(void)
|
|
||||||
{
|
|
||||||
send_int(0x5a5a5a5a);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ident_and_download_kernel(void *buffer, int maxlength)
|
|
||||||
{
|
|
||||||
int length;
|
|
||||||
unsigned int crc;
|
|
||||||
int i;
|
|
||||||
char msgtype;
|
|
||||||
unsigned char *_buffer = buffer;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
receive_sync();
|
|
||||||
msgtype = receive_char();
|
|
||||||
if(msgtype == MSGTYPE_REQUEST_IDENT) {
|
|
||||||
send_int(0x41524f52); /* "AROR" - ARTIQ runtime on OpenRISC */
|
|
||||||
send_int(1000000000000LL/identifier_frequency_read()); /* RTIO clock period in picoseconds */
|
|
||||||
} else if(msgtype == MSGTYPE_LOAD_KERNEL) {
|
|
||||||
length = receive_int();
|
|
||||||
if(length > maxlength) {
|
|
||||||
send_char(0x4c); /* Incorrect length */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
crc = receive_int();
|
|
||||||
for(i=0;i<length;i++)
|
|
||||||
_buffer[i] = receive_char();
|
|
||||||
if(crc32(buffer, length) != crc) {
|
|
||||||
send_char(0x43); /* CRC failed */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
send_char(0x4f); /* kernel reception OK */
|
|
||||||
return length;
|
|
||||||
} else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rpc(int rpc_num, int n_args, ...)
|
|
||||||
{
|
|
||||||
send_sync();
|
|
||||||
send_char(MSGTYPE_RPC_REQUEST);
|
|
||||||
send_sint(rpc_num);
|
|
||||||
send_char(n_args);
|
|
||||||
|
|
||||||
va_list args;
|
|
||||||
va_start(args, n_args);
|
|
||||||
while(n_args--)
|
|
||||||
send_int(va_arg(args, int));
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
return receive_int();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gpio_set(int channel, int value)
|
|
||||||
{
|
|
||||||
static int csr_value;
|
|
||||||
|
|
||||||
if(value)
|
|
||||||
csr_value |= 1 << channel;
|
|
||||||
else
|
|
||||||
csr_value &= ~(1 << channel);
|
|
||||||
leds_out_write(csr_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rtio_set(long long int timestamp, int channel, int value)
|
|
||||||
{
|
|
||||||
rtio_reset_write(0);
|
|
||||||
rtio_chan_sel_write(channel);
|
|
||||||
rtio_o_timestamp_write(timestamp);
|
|
||||||
rtio_o_value_write(value);
|
|
||||||
while(!rtio_o_writable_read());
|
|
||||||
rtio_o_we_write(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rtio_sync(int channel)
|
|
||||||
{
|
|
||||||
rtio_chan_sel_write(channel);
|
|
||||||
while(rtio_o_level_read() != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DDS_FTW0 0x0a
|
|
||||||
#define DDS_FTW1 0x0b
|
|
||||||
#define DDS_FTW2 0x0c
|
|
||||||
#define DDS_FTW3 0x0d
|
|
||||||
#define DDS_FUD 0x40
|
|
||||||
#define DDS_GPIO 0x41
|
|
||||||
|
|
||||||
#define DDS_READ(addr) \
|
|
||||||
MMPTR(0xb0000000 + (addr)*4)
|
|
||||||
|
|
||||||
#define DDS_WRITE(addr, data) \
|
|
||||||
MMPTR(0xb0000000 + (addr)*4) = data
|
|
||||||
|
|
||||||
static void dds_program(int channel, int ftw)
|
|
||||||
{
|
|
||||||
DDS_WRITE(DDS_GPIO, channel);
|
|
||||||
DDS_WRITE(DDS_FTW0, ftw & 0xff);
|
|
||||||
DDS_WRITE(DDS_FTW1, (ftw >> 8) & 0xff);
|
|
||||||
DDS_WRITE(DDS_FTW2, (ftw >> 16) & 0xff);
|
|
||||||
DDS_WRITE(DDS_FTW3, (ftw >> 24) & 0xff);
|
|
||||||
DDS_WRITE(DDS_FUD, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct symbol syscalls[] = {
|
|
||||||
{"__syscall_rpc", rpc},
|
|
||||||
{"__syscall_gpio_set", gpio_set},
|
|
||||||
{"__syscall_rtio_set", rtio_set},
|
|
||||||
{"__syscall_rtio_sync", rtio_sync},
|
|
||||||
{"__syscall_dds_program", dds_program},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static void dds_init(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
DDS_WRITE(DDS_GPIO, 1 << 7);
|
|
||||||
|
|
||||||
for(i=0;i<8;i++) {
|
|
||||||
DDS_WRITE(DDS_GPIO, i);
|
|
||||||
DDS_WRITE(0x00, 0x78);
|
|
||||||
DDS_WRITE(0x01, 0x00);
|
|
||||||
DDS_WRITE(0x02, 0x00);
|
|
||||||
DDS_WRITE(0x03, 0x00);
|
|
||||||
DDS_WRITE(DDS_FUD, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef void (*kernel_function)(void);
|
typedef void (*kernel_function)(void);
|
||||||
|
|
||||||
|
@ -222,16 +27,15 @@ int main(void)
|
||||||
while(1) {
|
while(1) {
|
||||||
length = ident_and_download_kernel(kbuf, sizeof(kbuf));
|
length = ident_and_download_kernel(kbuf, sizeof(kbuf));
|
||||||
if(length > 0) {
|
if(length > 0) {
|
||||||
if(load_elf(syscalls, kbuf, length, kcode, sizeof(kcode))) {
|
if(load_elf(resolve_symbol, kbuf, length, kcode, sizeof(kcode))) {
|
||||||
flush_cpu_icache();
|
rtio_init();
|
||||||
dds_init();
|
dds_init();
|
||||||
|
flush_cpu_icache();
|
||||||
k();
|
k();
|
||||||
rtio_reset_write(1);
|
kernel_finished();
|
||||||
send_sync();
|
|
||||||
send_char(MSGTYPE_KERNEL_FINISHED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <generated/csr.h>
|
||||||
|
|
||||||
|
#include "rtio.h"
|
||||||
|
|
||||||
|
void rtio_init(void)
|
||||||
|
{
|
||||||
|
rtio_reset_write(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtio_set(long long int timestamp, int channel, int value)
|
||||||
|
{
|
||||||
|
rtio_reset_write(0);
|
||||||
|
rtio_chan_sel_write(channel);
|
||||||
|
rtio_o_timestamp_write(timestamp);
|
||||||
|
rtio_o_value_write(value);
|
||||||
|
while(!rtio_o_writable_read());
|
||||||
|
rtio_o_we_write(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtio_sync(int channel)
|
||||||
|
{
|
||||||
|
rtio_chan_sel_write(channel);
|
||||||
|
while(rtio_o_level_read() != 0);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __RTIO_H
|
||||||
|
#define __RTIO_H
|
||||||
|
|
||||||
|
void rtio_init(void);
|
||||||
|
void rtio_set(long long int timestamp, int channel, int value);
|
||||||
|
void rtio_sync(int channel);
|
||||||
|
|
||||||
|
#endif /* __RTIO_H */
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "elf_loader.h"
|
||||||
|
#include "corecom.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "rtio.h"
|
||||||
|
#include "dds.h"
|
||||||
|
#include "symbols.h"
|
||||||
|
|
||||||
|
static const struct symbol syscalls[] = {
|
||||||
|
{"rpc", rpc},
|
||||||
|
{"gpio_set", gpio_set},
|
||||||
|
{"rtio_set", rtio_set},
|
||||||
|
{"rtio_sync", rtio_sync},
|
||||||
|
{"dds_program", dds_program},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static long long int gcd64(long long int a, long long int b)
|
||||||
|
{
|
||||||
|
long long int c;
|
||||||
|
|
||||||
|
while(a) {
|
||||||
|
c = a;
|
||||||
|
a = b % a;
|
||||||
|
b = c;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct symbol arithmetic[] = {
|
||||||
|
{"__gcd64", gcd64},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
void *resolve_symbol(const char *name)
|
||||||
|
{
|
||||||
|
if(strncmp(name, "__syscall_", 10) == 0)
|
||||||
|
return find_symbol(syscalls, name + 10);
|
||||||
|
return find_symbol(arithmetic, name);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef __SYMBOLS_H
|
||||||
|
#define __SYMBOLS_H
|
||||||
|
|
||||||
|
void *resolve_symbol(const char *name);
|
||||||
|
|
||||||
|
#endif /* __SYMBOLS_H */
|
Loading…
Reference in New Issue