/* * * Copyright (C) 2007-2009, IBM Corporation, * Eric Van Hensbergen (bergevan@us.ibm.com) * * Description: primitive JTAG console implementation * * All rights reserved * */ #include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h" typedef struct Mb Mb;typedef struct Md Md;typedef struct Mm Mm; /* * Mailbox Descriptor. * Offset is from 0x7ffff8000ull. Length includes the message * header, and may be 0 if the mailbox isn't present. * The table of mailbox descriptors must be at 0x7ffffffd0ull. * There are 2 descriptors per mailbox, one for input and * one for output. */struct Md { u16int offset; u16int length;}; /* * Mailbox Message. * A descriptor points to one of these. * The MSb of cmd is an acknowledge * Result is set by the reader and may be ignored. * A crc of 0 means none was calculated. */struct Mm { u16int cmd; u16int len; u16int result; u16int crc; u8int data[];}; /* * Soft mailbox. */struct Mb { Mm* mm; usize len;}; enum { NMb = 4, Mdtable = VIRTSRAM+0x7fd0,}; #define BGP_DCR_TEST(x) (0x400+(x))#define BGP_DCR_GLOB_ATT_WRITE_SET BGP_DCR_TEST(0x17)#define BGP_DCR_GLOB_ATT_WRITE_CLEAR BGP_DCR_TEST(0x18)#define BGP_ALERT_OUT(core) (0x80000000u>>(24+(core)))#define BGP_ALERT_IN(core) (0x80000000u>>(28+(core)))#define BGP_JMB_CMD2HOST_PRINT (0x0002) static Mb mbi[NMb];static Mb mbo[NMb]; voidmbinit(void){ int i; Mb *mb; Md *md; md = (Md*)Mdtable; for(i = 0; i < NMb; i++){ mb = &mbi[i]; if(md->length != 0){ mb->mm = (Mm*)(VIRTSRAM+md->offset); mb->len = md->length - offsetof(Mm, data[0]); } md++; mb = &mbo[i]; if(md->length != 0){ mb->mm = (Mm*)(VIRTSRAM+md->offset); mb->len = md->length - offsetof(Mm, data[0]); } md++; }} static intmbputs(int core, char* s, int n){ Mb *mb; Mm *mm; int len, r; if(core >= sys->ncores) return -1; mb = &mbo[core]; if((mm = mb->mm) == nil) return -1; r = n; while(n > 0){ if(n > mb->len) len = mb->len; else len = n; memmove(mm->data, s, len); mm->len = len; mm->cmd = BGP_JMB_CMD2HOST_PRINT; imb(); dcrput(BGP_DCR_GLOB_ATT_WRITE_SET, BGP_ALERT_OUT(core)); do{ dcbi(&mm->cmd); }while(!(mm->cmd & 0x8000)); //dcrput(BGP_DCR_GLOB_ATT_WRITE_CLEAR, BGP_ALERT_OUT(core)); n -= len; s += len; } return r;} intmbconsputs(char* s, int n){ return mbputs(m->machno, s, n);}
/*
*
* Copyright (C) 2007-2009, IBM Corporation,
* Eric Van Hensbergen (bergevan@us.ibm.com)
*
* Description: primitive JTAG console implementation
*
* All rights reserved
*
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
typedef struct Mb Mb;
typedef struct Md Md;
typedef struct Mm Mm;
/*
* Mailbox Descriptor.
* Offset is from 0x7ffff8000ull. Length includes the message
* header, and may be 0 if the mailbox isn't present.
* The table of mailbox descriptors must be at 0x7ffffffd0ull.
* There are 2 descriptors per mailbox, one for input and
* one for output.
*/
struct Md {
u16int offset;
u16int length;
};
/*
* Mailbox Message.
* A descriptor points to one of these.
* The MSb of cmd is an acknowledge
* Result is set by the reader and may be ignored.
* A crc of 0 means none was calculated.
*/
struct Mm {
u16int cmd;
u16int len;
u16int result;
u16int crc;
u8int data[];
};
/*
* Soft mailbox.
*/
struct Mb {
Mm* mm;
usize len;
};
enum {
NMb = 4,
Mdtable = VIRTSRAM+0x7fd0,
};
#define BGP_DCR_TEST(x) (0x400+(x))
#define BGP_DCR_GLOB_ATT_WRITE_SET BGP_DCR_TEST(0x17)
#define BGP_DCR_GLOB_ATT_WRITE_CLEAR BGP_DCR_TEST(0x18)
#define BGP_ALERT_OUT(core) (0x80000000u>>(24+(core)))
#define BGP_ALERT_IN(core) (0x80000000u>>(28+(core)))
#define BGP_JMB_CMD2HOST_PRINT (0x0002)
static Mb mbi[NMb];
static Mb mbo[NMb];
void
mbinit(void)
{
int i;
Mb *mb;
Md *md;
md = (Md*)Mdtable;
for(i = 0; i < NMb; i++){
mb = &mbi[i];
if(md->length != 0){
mb->mm = (Mm*)(VIRTSRAM+md->offset);
mb->len = md->length - offsetof(Mm, data[0]);
}
md++;
mb = &mbo[i];
if(md->length != 0){
mb->mm = (Mm*)(VIRTSRAM+md->offset);
mb->len = md->length - offsetof(Mm, data[0]);
}
md++;
}
}
static int
mbputs(int core, char* s, int n)
{
Mb *mb;
Mm *mm;
int len, r;
if(core >= sys->ncores)
return -1;
mb = &mbo[core];
if((mm = mb->mm) == nil)
return -1;
r = n;
while(n > 0){
if(n > mb->len)
len = mb->len;
else
len = n;
memmove(mm->data, s, len);
mm->len = len;
mm->cmd = BGP_JMB_CMD2HOST_PRINT;
imb();
dcrput(BGP_DCR_GLOB_ATT_WRITE_SET, BGP_ALERT_OUT(core));
do{
dcbi(&mm->cmd);
}while(!(mm->cmd & 0x8000));
//dcrput(BGP_DCR_GLOB_ATT_WRITE_CLEAR, BGP_ALERT_OUT(core));
n -= len;
s += len;
}
return r;
}
int
mbconsputs(char* s, int n)
{
return mbputs(m->machno, s, n);
}