parent
38c56c7c1f
commit
963b88fb0b
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tom King <ka6sox@gmail.com>
|
||||
* (C) 2013 Ian McMahon <ian.mcmahon@prototechnical.com>
|
||||
* (C) 2014 Timothy Pearson <kb9vqf@pearsoncomputing.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/ {
|
||||
compatible = "ti,beaglebone", "ti,beaglebone-black";
|
||||
|
||||
/* identification */
|
||||
manufacturer = "Raptor Engineering";
|
||||
board-name = "Universal Laboratory Debug Control Interface";
|
||||
model = "ULABCTL001";
|
||||
part-number = "BB-BONE-ULAB";
|
||||
version = "0001";
|
||||
|
||||
/* state the resources this cape uses */
|
||||
exclusive-use =
|
||||
/* the pin header uses */
|
||||
"P8.45", /* GPMC: gpmc_a0 */
|
||||
"P8.46", /* GPMC: gpmc_a1 */
|
||||
"P9.14", /* GPMC: gpmc_a2 */
|
||||
"P8.44", /* GPMC: gpmc_a3 */
|
||||
"P8.41", /* GPMC: gpmc_a4 */
|
||||
"P8.42", /* GPMC: gpmc_a5 */
|
||||
"P8.39", /* GPMC: gpmc_a6 */
|
||||
"P8.40", /* GPMC: gpmc_a7 */
|
||||
"P8.27", /* GPMC: gpmc_a8 */
|
||||
"P8.29", /* GPMC: gpmc_a9 */
|
||||
"P8.28", /* GPMC: gpmc_a10 */
|
||||
"P8.30", /* GPMC: gpmc_a11 */
|
||||
"P8.37", /* GPMC: gpmc_a12 */
|
||||
"P8.38", /* GPMC: gpmc_a13 */
|
||||
"P8.36", /* GPMC: gpmc_a14 */
|
||||
"P8.34", /* GPMC: gpmc_a15 */
|
||||
"P8.35", /* GPMC: gpmc_a16 */
|
||||
"P8.33", /* GPMC: gpmc_a17 */
|
||||
"P8.31", /* GPMC: gpmc_a18 */
|
||||
"P8.32", /* GPMC: gpmc_a19 */
|
||||
|
||||
"P8.25", /* GPMC: gpmc_ad0 */
|
||||
"P8.24", /* GPMC: gpmc_ad1 */
|
||||
"P8.5", /* GPMC: gpmc_ad2 */
|
||||
"P8.6", /* GPMC: gpmc_ad3 */
|
||||
"P8.23", /* GPMC: gpmc_ad4 */
|
||||
"P8.22", /* GPMC: gpmc_ad5 */
|
||||
"P8.3", /* GPMC: gpmc_ad6 */
|
||||
"P8.4", /* GPMC: gpmc_ad7 */
|
||||
|
||||
"P8.7", /* GPMC: gpmc_advn_ale */
|
||||
"P8.8", /* GPMC: gpmc_oen_ren */
|
||||
"P8.10", /* GPMC: gpmc_wen */
|
||||
|
||||
"P9.11", /* GPIO: gpio0[30] */
|
||||
"P9.13", /* GPIO: gpio0[31] */
|
||||
"P9.21", /* GPIO: gpio0[3] */
|
||||
"P9.22", /* GPIO: gpio0[2] */
|
||||
|
||||
"P8.43", /* GPIO: boot select */
|
||||
|
||||
/* the hardware IP this cape uses */
|
||||
"GPMC";
|
||||
|
||||
fragment@0 {
|
||||
target = <&am33xx_pinmux>;
|
||||
__overlay__ {
|
||||
bb_gpmc_pins: pinmux_bb_gpmc_pins {
|
||||
pinctrl-single,pins = <
|
||||
|
||||
/* address bus */
|
||||
0x0a0 0x01 /* gpmc_a0, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0a4 0x01 /* gpmc_a1, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x048 0x00 /* gpmc_a2, OUTPUT_PULLDOWN | MODE0 */
|
||||
0x0ac 0x01 /* gpmc_a3, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0b0 0x01 /* gpmc_a4, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0b4 0x01 /* gpmc_a5, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0b8 0x01 /* gpmc_a6, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0bc 0x01 /* gpmc_a7, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0e0 0x01 /* gpmc_a8, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0e4 0x01 /* gpmc_a9, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0e8 0x01 /* gpmc_a10, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0ec 0x01 /* gpmc_a11, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0c0 0x01 /* gpmc_a12, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0c4 0x01 /* gpmc_a13, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0c8 0x01 /* gpmc_a14, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0cc 0x01 /* gpmc_a15, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0d0 0x01 /* gpmc_a16, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0d4 0x01 /* gpmc_a17, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0d8 0x01 /* gpmc_a18, OUTPUT_PULLDOWN | MODE1 */
|
||||
0x0dc 0x01 /* gpmc_a19, OUTPUT_PULLDOWN | MODE1 */
|
||||
|
||||
/* address/data muxed bus */
|
||||
0x000 0x30 /* gpmc_ad0, INPUT_PULLUP | MODE0 */
|
||||
0x004 0x30 /* gpmc_ad1, INPUT_PULLUP | MODE0 */
|
||||
0x008 0x30 /* gpmc_ad2, INPUT_PULLUP | MODE0 */
|
||||
0x00c 0x30 /* gpmc_ad3, INPUT_PULLUP | MODE0 */
|
||||
0x010 0x30 /* gpmc_ad4, INPUT_PULLUP | MODE0 */
|
||||
0x014 0x30 /* gpmc_ad5, INPUT_PULLUP | MODE0 */
|
||||
0x018 0x30 /* gpmc_ad6, INPUT_PULLUP | MODE0 */
|
||||
0x01c 0x30 /* gpmc_ad7, INPUT_PULLUP | MODE0 */
|
||||
|
||||
/* control */
|
||||
0x090 0x10 /* gpmc_advn_ale, OUTPUT_PULLUP | MODE0 */
|
||||
0x094 0x10 /* gpmc_oen_ren, OUTPUT_PULLUP | MODE0 */
|
||||
0x098 0x10 /* gpmc_wen, OUTPUT_PULLUP | MODE0 */
|
||||
|
||||
/* gpio */
|
||||
0x070 0x07 /* gpio0[30], OUTPUT_PULLDOWN | MODE7 */
|
||||
0x074 0x07 /* gpio0[31], OUTPUT_PULLDOWN | MODE7 */
|
||||
0x154 0x27 /* gpio0[3], INPUT_PULLDOWN | MODE7 */
|
||||
0x150 0x07 /* gpio0[2], OUTPUT_PULLDOWN | MODE7 */
|
||||
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fragment@1 {
|
||||
target = <&gpmc>;
|
||||
depth = <1>; /* only create devices on depth 1 */
|
||||
|
||||
/* stupid warnings */
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
__overlay__ {
|
||||
status = "okay";
|
||||
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&bb_gpmc_pins>;
|
||||
|
||||
/* chip select ranges */
|
||||
ranges = <0 0 0x10000000 0x02000000>; /* CS0 @addr 0x01000000, size 0x02000000 */
|
||||
|
||||
sram@0 {
|
||||
compatible = "raptorengineering,ulab","sram";
|
||||
address-cells = <1>;
|
||||
size-cells = <1>;
|
||||
bank-width = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,47 @@
|
||||
# Copyright (C) 2014 Timothy Pearson
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AR = ar
|
||||
RANLIB = ranlib
|
||||
CC = gcc
|
||||
|
||||
CFLAGS += -Wall -Os -ggdb -MD
|
||||
#CFLAGS += -Wextra -Wno-unused-parameter -Werror
|
||||
|
||||
help:
|
||||
@echo ""
|
||||
@echo "Usage:"
|
||||
@echo ""
|
||||
@echo " $(MAKE) bbb-gpmc-test"
|
||||
@echo " .... build bbb-gpmc-test"
|
||||
@echo ""
|
||||
@echo " $(MAKE) all"
|
||||
@echo " .... build everything"
|
||||
@echo ""
|
||||
@echo " $(MAKE) install"
|
||||
@echo " .... install everything in /usr/"
|
||||
@echo ""
|
||||
|
||||
all: bbb-gpmc-test
|
||||
|
||||
install: all
|
||||
install -Dt /usr/bin/ bbb-gpmc-test
|
||||
|
||||
bbb-gpmc-test: bbb-gpmc-test.o
|
||||
|
||||
clean:
|
||||
rm -f bbb-gpmc-test.o
|
||||
|
||||
-include *.d
|
||||
|
@ -0,0 +1,3 @@
|
||||
Disable eMMC in uEnv.txt
|
||||
Comment out eMMC block in /boot/dtbs/am335x-boneblack.dts (mmc@481d8000)
|
||||
Compile and install uLab cape (BB-ULAB-00A0.dts) in /lib/firmware, then load it via the cape manager
|
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* bbb-gpmc-test
|
||||
*
|
||||
* Copyright (C) 2014 Timothy Pearson <kb9vqf@pearsoncomputing.net> (Beaglebone Black)
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/** BEGIN: Low-Level I/O Implementation **/
|
||||
|
||||
// Beaglebone Black GPMC driver
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define MEMORY_SPACE_ADDRESS_BITS 15
|
||||
|
||||
#define GPMC_BASE 0x50000000
|
||||
#define GPMC_REGLEN 0x10000000
|
||||
|
||||
#define GPMC_CHIPSELECTCONFIGDISPLACEMENT (0x30 / 4)
|
||||
|
||||
#define GPMC_CONFIG (0x50 / 4)
|
||||
#define GPMC_CONFIG1 (0x60 / 4)
|
||||
#define GPMC_CONFIG2 (0x64 / 4)
|
||||
#define GPMC_CONFIG3 (0x68 / 4)
|
||||
#define GPMC_CONFIG4 (0x6c / 4)
|
||||
#define GPMC_CONFIG5 (0x70 / 4)
|
||||
#define GPMC_CONFIG6 (0x74 / 4)
|
||||
#define GPMC_CONFIG7 (0x78 / 4)
|
||||
|
||||
#define MEMORY_SIZE (1 << MEMORY_SPACE_ADDRESS_BITS)
|
||||
|
||||
int mem_fd = 0;
|
||||
int gpmc_mem_fd = 0;
|
||||
char *gpio_mem, *gpio_map, *gpmc_map;
|
||||
|
||||
// I/O access
|
||||
static volatile unsigned int *gpio = NULL;
|
||||
static volatile unsigned char *gpio_char = NULL;
|
||||
static volatile unsigned int *gpmc = NULL;
|
||||
|
||||
static void gpmc_mapregisters()
|
||||
{
|
||||
/* open /dev/mem */
|
||||
if ((gpmc_mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
|
||||
printf("can't open /dev/mem \n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
/* mmap GPMC */
|
||||
gpmc_map = (char *)mmap(
|
||||
0,
|
||||
GPMC_REGLEN,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
gpmc_mem_fd,
|
||||
GPMC_BASE
|
||||
);
|
||||
|
||||
if (gpmc_map == MAP_FAILED) {
|
||||
printf("mmap error %d\n", (int)gpmc_map);
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
// Always use volatile pointer!
|
||||
gpmc = (volatile unsigned *)gpmc_map;
|
||||
}
|
||||
|
||||
static void gpmc_unmapregisters()
|
||||
{
|
||||
munmap((void*) gpmc, GPMC_REGLEN);
|
||||
if (gpmc_mem_fd != -1) {
|
||||
close(gpmc_mem_fd);
|
||||
}
|
||||
}
|
||||
|
||||
static void gpmc_setup(void)
|
||||
{
|
||||
// WARNING: The GPMC runs at the L3 clock frequency!
|
||||
// It is not well documented, but that frequency seems to be 200MHz on the AM335x series of chips
|
||||
|
||||
gpmc_mapregisters();
|
||||
|
||||
if (gpmc != NULL) {
|
||||
int chipselect = 0;
|
||||
int displacement = GPMC_CHIPSELECTCONFIGDISPLACEMENT * chipselect;
|
||||
|
||||
// disable before playing with the registers
|
||||
*(gpmc + displacement + GPMC_CONFIG7) = 0x00000000;
|
||||
|
||||
*(gpmc + displacement + GPMC_CONFIG) = 0x00000000; // Unlimited address space
|
||||
*(gpmc + displacement + GPMC_CONFIG1) = 0x00000000; // No burst, async, 8-bit, non multiplexed
|
||||
|
||||
// // 200MHz compatible SRAM device
|
||||
// *(gpmc + displacement + GPMC_CONFIG2) = 0x00000800; // Assert CS on fclk 0, deassert CS on fclk 8
|
||||
// *(gpmc + displacement + GPMC_CONFIG3) = 0x00000200; // Assert ADV on fclk0, deassert ADV on fclk2
|
||||
// *(gpmc + displacement + GPMC_CONFIG4) = 0x06020802; // Assert WE on fclk2, deassert WE on fclk6, assert OE on fclk2, deassert OE on fclk8
|
||||
// *(gpmc + displacement + GPMC_CONFIG5) = 0x00060808; // Data valid on fclk 6, cycle time 8 fclks
|
||||
|
||||
// 100MHz compatible SRAM device
|
||||
*(gpmc + displacement + GPMC_CONFIG2) = 0x00001000; // Assert CS on fclk0, deassert CS on fclk16
|
||||
*(gpmc + displacement + GPMC_CONFIG3) = 0x00000400; // Assert ADV on fclk 0, deassert ADV on fclk 4
|
||||
*(gpmc + displacement + GPMC_CONFIG4) = 0x0c041004; // Assert WE on fclk4, deassert WE on fclk12, assert OE on fclk4, deassert OE on fclk16
|
||||
*(gpmc + displacement + GPMC_CONFIG5) = 0x000c1010; // Data valid on fclk 12, cycle time 16 fclks
|
||||
|
||||
*(gpmc + displacement + GPMC_CONFIG6) = 0x00000000; // No back to back cycle restrictions
|
||||
*(gpmc + displacement + GPMC_CONFIG7) = 0x00000e50; // CS0: Set base address 0x10000000, 32MB region, and enable CS
|
||||
|
||||
gpmc_unmapregisters();
|
||||
}
|
||||
}
|
||||
|
||||
static void io_setup(void)
|
||||
{
|
||||
printf("sizeof int:\t%d\n", sizeof(int));
|
||||
|
||||
/* open /dev/mem */
|
||||
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
|
||||
printf("can't open /dev/mem \n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
/* mmap GPIO */
|
||||
gpio_map = (char *)mmap(
|
||||
0,
|
||||
MEMORY_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
mem_fd,
|
||||
0x10000000
|
||||
);
|
||||
|
||||
if (gpio_map == MAP_FAILED) {
|
||||
printf("mmap error %d\n", (int)gpio_map);
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
// Always use volatile pointer!
|
||||
gpio = (volatile unsigned *)gpio_map;
|
||||
gpio_char = (volatile unsigned char *)gpio_map;
|
||||
|
||||
// Select a test from the following blocks of code...
|
||||
|
||||
// // DEBUG ONLY
|
||||
// // Clear out the mapped memory
|
||||
// int i;
|
||||
// for (i=0;i<0x3ff; i++) {
|
||||
// *(gpio + i) = 0x00000000;
|
||||
// }
|
||||
|
||||
// DEBUG ONLY
|
||||
// Fill the mapped memory with a test pattern
|
||||
// int j;
|
||||
// for (j=0;j<0x00001000; j++) {
|
||||
// *(gpio + j) = j;
|
||||
// }
|
||||
// int j;
|
||||
// for (j=0;j<0x3ff; j++) {
|
||||
// *(gpio + j) = j;
|
||||
// }
|
||||
int j;
|
||||
for (j=0;j<MEMORY_SIZE; j++) {
|
||||
*(gpio_char + j) = ((unsigned char)j);
|
||||
}
|
||||
|
||||
// DEBUG ONLY
|
||||
// Prints the contents of the mapped memory
|
||||
int k;
|
||||
for (k=0;k<(MEMORY_SIZE/4); k++) {
|
||||
printf("0x%08x\t%08x\n", k, *(gpio + k));
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
// // DEBUG ONLY
|
||||
// // Excercise the memory space
|
||||
// int l;
|
||||
// while (1) {
|
||||
// for (l=0;l<(MEMORY_SIZE/4); l++) {
|
||||
// k = *(gpio + l);
|
||||
// }
|
||||
// }
|
||||
|
||||
// while (1) {
|
||||
// printf("0x%08x\t0x%08x\t0x%08x\t0x%08x\r", *(gpio + 0), *(gpio + 1), *(gpio + 2), *(gpio + 3));
|
||||
// usleep(1);
|
||||
// }
|
||||
|
||||
// while (1) {
|
||||
// printf("0x%08x\t0x%08x\t0x%08x\t0x%08x\r", *(gpio + 3), *(gpio + 2), *(gpio + 1), *(gpio + 0));
|
||||
// usleep(1);
|
||||
// }
|
||||
|
||||
// printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\n\r", *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0), *(gpio_char + 0));
|
||||
//
|
||||
while (1) {
|
||||
// printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\r", *(gpio_char + 0), *(gpio_char + 1), *(gpio_char + 2), *(gpio_char + 3), *(gpio_char + 4), *(gpio_char + 5), *(gpio_char + 6), *(gpio_char + 7));
|
||||
// printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\r", *(gpio_char + 0), *(gpio_char + 1), *(gpio_char + 2), *(gpio_char + 3), *(gpio_char + 0x1000), *(gpio_char + 0x1001), *(gpio_char + 0x1002), *(gpio_char + 0x1003));
|
||||
printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\r", *(gpio_char + 0), *(gpio_char + 1), *(gpio_char + 2), *(gpio_char + 3), *(gpio_char + 0x4000), *(gpio_char + 0x4001), *(gpio_char + 0x4002), *(gpio_char + 0x4003));
|
||||
// printf("0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\t0x%02x\r", *(gpio_char + 0x4000), *(gpio_char + 0x4001), *(gpio_char + 0x4002), *(gpio_char + 0x4003), *(gpio_char + 0x4000), *(gpio_char + 0x4001), *(gpio_char + 0x4002), *(gpio_char + 0x4003));
|
||||
usleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
static void io_shutdown(void)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/** END: Low-Level I/O Implementation **/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
gpmc_setup();
|
||||
printf("GPMC setup complete!\n"); fflush(stdout);
|
||||
io_setup();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in new issue