blob: 2c0fc2343cace60468365d96d934277c55b633bc [file] [log] [blame] [edit]
#include <ros/resource.h>
#include <ros/procdata.h>
#include <ros/event.h>
#include <ros/bcq.h>
#include <parlib.h>
#include <vcore.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <arch/arch.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <timing.h>
#include <assert.h>
#include <event.h>
#include <uthread.h>
void *core0_tls = 0;
void *in_buf, *out_buf;
/* Test program for the audio device. mmap()s the stuff, sets up a notif
* handler, and switches to multi_mode.
*
* Note: this has a lot of mhello-like MCP infrastructure. When Lithe is
* working, you won't need any of this. Just the mmap stuff and the notif
* handler. Stuff specific to the ethernet audio device is marked ETH_AUD. */
int main()
{
int retval;
int in_fd, out_fd;
/* ETHAUD mmap the input and output buffers */
in_fd = open("/dev/eth_audio_in", O_RDONLY);
out_fd = open("/dev/eth_audio_out", O_RDWR);
assert(in_fd != -1);
assert(out_fd != -1);
in_buf = mmap(0, PGSIZE, PROT_READ, 0, in_fd, 0);
if (in_buf == MAP_FAILED) {
int err = errno;
perror("Can't mmap the input buf:");
}
out_buf = mmap(0, PGSIZE, PROT_READ | PROT_WRITE, MAP_POPULATE, out_fd, 0);
if (out_buf == MAP_FAILED) {
int err = errno;
perror("Can't mmap the output buf:");
}
//strncpy(out_buf, "Nanwan loves you!\n", 19);
/* begin: stuff userspace needs to do before switching to multi-mode */
vcore_init();
/* ETHAUD Turn on Free apple pie (which is the network packet) */
enable_kevent(EV_FREE_APPLE_PIE, 0, EVENT_IPI);
/* Need to save this somewhere that you can find it again when restarting
* core0 */
core0_tls = get_tls_desc(0);
/* Need to save our floating point state somewhere (like in the
* user_thread_tcb so it can be restarted too */
/* end: stuff userspace needs to do before switching to multi-mode */
/* ETHAUD */
/* Switch into _M mode */
retval = vcore_request(1);
/* Stay alive for a minute (will take interrupts) */
udelay(60000000);
printf("Eth aud, finishing up!\n");
/* Need to do unmap it, due to some limitations in the kernel */
munmap(in_buf, PGSIZE);
munmap(out_buf, PGSIZE);
close(in_fd);
close(out_fd);
}
/* ETHAUD, with some debugging commands... */
void process_packet(void)
{
//printf("Received a packet!\n");
//memset(out_buf, 0, PGSIZE);
memcpy(out_buf, in_buf, 1280); /* size of the payload. */
memset(out_buf + 1280, 0, 4); /* 4 bytes of control info. */
//printf("contents of out_buf %s\n", out_buf);
}
void vcore_entry(void)
{
uint32_t vcoreid = vcore_id();
static bool first_time = TRUE;
printf("GIANT WARNING: this is ancient shit\n");
/* begin: stuff userspace needs to do to handle events/notifications */
struct vcore *vc = &__procinfo.vcoremap[vcoreid];
struct preempt_data *vcpd;
vcpd = &__procdata.vcore_preempt_data[vcoreid];
/* Ghetto way to get just an event number */
unsigned int ev_type = get_event_type(&vcpd->ev_mbox_public);
/* ETHAUD app: process the packet if we got a notif */
if (ev_type == EV_FREE_APPLE_PIE)
process_packet();
if (vc->preempt_pending) {
printf("Oh crap, vcore %d is being preempted! Yielding\n", vcoreid);
sys_yield(TRUE);
printf("After yield on vcore %d. I wasn't being preempted.\n", vcoreid);
}
/* Lets try to restart vcore0's context. Note this doesn't do anything to
* set the appropriate TLS. On x86, this will involve changing the LDT
* entry for this vcore to point to the TCB of the new user-thread. */
if (vcoreid == 0) {
handle_events(vcoreid);
set_tls_desc(core0_tls, 0);
assert(__vcoreid == 0); /* in case anyone uses this */
/* Load silly state (Floating point) too */
pop_user_ctx(&vcpd->uthread_ctx, vcoreid);
printf("should never see me!");
}
/* unmask notifications once you can let go of the uthread_ctx and it is
* okay to clobber the transition stack.
* Check Documentation/processes.txt: 4.2.4. In real code, you should be
* popping the tf of whatever user process you want (get off the x-stack) */
vcpd->notif_disabled = FALSE;
/* end: stuff userspace needs to do to handle notifications */
/* The other vcores will hit here. */
while (1)
cpu_relax();
}