修复部分syscall的BUG

This commit is contained in:
XIAOYI12 2024-09-02 14:05:39 +08:00
parent 37677878c0
commit ab6763337a
7 changed files with 274 additions and 190 deletions

View File

@ -6,45 +6,32 @@ void print_info(){
struct sysinfo *info = get_sysinfo();
printf(" .:=*#&&@@@@@@&&#+=:. \n"
" -+&@@@@@@@@@@@@@@@@@@@- ----------. -----------------\n"
" -*@@@@@@@@@@@@@@@@@@@@&=.-&@@@@@@@@@@+ OSName: %s\n"
" =&@@@@@@@@@@@@@@@@@@@@@=.-&@@@@@@@@@@@@+ Kernel: %s\n"
" -&@@@@@@@@@@@@@@@@@@@@@=.-&@@@@@@@@@@@@@@+ CPU Vendor: %s\n"
" *@@@@@@@@@@@@@@@@@@@@@=.-&@@@@@@@@@@@@@@@@+ CPU: %s\n"
" .&@@@@@@@@@@@@@@@&*=-:: :#@@@@@@@@@@@@@@@@@@= Memory: %dMB\n"
" &@@@@@@@@@@@@@&=. #@@@@@@@@@@@@@@@@@#:.= Console: CPOS_USER_SHELL\n"
" *@@@@@@@@@@@@@- #@@@@@@@@@@@@@@@#:.=@@+ PCI Device: %d\n"
":@@@@@@@@@@@@&. #@@@@@@@@@@@@@#: =@@@@@. Resolution: %d x %d\n"
"#@@@@@@@@@@@@. #@@@@@@@@@@@#: =@@@@@@@+ Time: %d/%d/%d %d:%d\n"
"@@@@@@@@@@@@+ *&&&&&&&&&#- =@@@@@@@@@&\n"
"@@@@@@@@@@@@- :@@@@@@@@@@@@\n"
"@@@@@@@@@@@@+ #@@@@@@@@@@@&\n"
"*@@@@@@@@@@@@. :@@@@@@@@@@@@+\n"
":@@@@@@@@@@@@&. :@@@@@@@@@@@@@.\n"
" *@@@@@@@@@@@@@= =@@@@@@@@@@@@@+ \n"
" #@@@@@@@@@@@@@&+: :+@@@@@@@@@@@@@@# \n"
" #@@@@@@@@@@@@@@@&*+=----=+#&@@@@@@@@@@@@@@@* \n"
" +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ \n"
" :&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#: \n"
" -#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#- \n"
" :*@@@@@@@@@@@@@@@@@@@@@@@@@@@&+: \n"
" :+#@@@@@@@@@@@@@@@@@@@@#+: \n"
" :=+*#&@@@@@@&#*+-: \n",
info->osname,
info->kenlname,
info->cpu_vendor,
info->cpu_name,
info->phy_mem_size,
info->pci_device,
info->frame_width,
info->frame_height,
info->year,
info->mon,
info->day,
info->hour,
info->min,
info->sec);
printf(" .:=*#&&@@@@@@&&#+=:. \n");
printf(" -+&@@@@@@@@@@@@@@@@@@@- \03300C5CD;----------.\033C6C6C6; -----------------\n");
printf(" -*@@@@@@@@@@@@@@@@@@@@&=\03300C5CD;.-&@@@@@@@@@@+\033C6C6C6; OSName: %s\n",info->osname);
printf(" =&@@@@@@@@@@@@@@@@@@@@@=\03300C5CD;.-&@@@@@@@@@@@@+\033C6C6C6; Kernel: %s\n",info->kenlname);
printf(" -&@@@@@@@@@@@@@@@@@@@@@=\03300C5CD;.-&@@@@@@@@@@@@@@+\033C6C6C6; CPU Vendor: %s\n",info->cpu_vendor);
printf(" *@@@@@@@@@@@@@@@@@@@@@=\03300C5CD;.-&@@@@@@@@@@@@@@@@+\033C6C6C6; CPU: %s\n",info->cpu_name);
printf(" .&@@@@@@@@@@@@@@@&*=-:: \03300C5CD;:#@@@@@@@@@@@@@@@@@@=\033C6C6C6; Memory: %dMB\n",info->phy_mem_size);
printf(" &@@@@@@@@@@@@@&=. \03300C5CD;#@@@@@@@@@@@@@@@@@#:.\033C6C6C6;= Console: CPOS_USER_SHELL\n");
printf(" *@@@@@@@@@@@@@- \03300C5CD;#@@@@@@@@@@@@@@@#:.\033C6C6C6;=@@+ PCI Device: %d\n",info->pci_device);
printf(":@@@@@@@@@@@@&. \03300C5CD;#@@@@@@@@@@@@@#:\033C6C6C6; =@@@@@. Resolution: %d x %d\n",info->frame_width,info->frame_height);
printf("#@@@@@@@@@@@@. \03300C5CD;#@@@@@@@@@@@#:\033C6C6C6; =@@@@@@@+ Time: %d/%d/%d %d:%d:%d\n",info->year,info->mon,
info->day,info->hour,info->min,info->sec);
printf("@@@@@@@@@@@@+ \03300C5CD;*&&&&&&&&&#-\033C6C6C6; =@@@@@@@@@&\n");
printf("@@@@@@@@@@@@- :@@@@@@@@@@@@\n");
printf("@@@@@@@@@@@@+ #@@@@@@@@@@@&\n");
printf("*@@@@@@@@@@@@. :@@@@@@@@@@@@+\n");
printf(":@@@@@@@@@@@@&. :@@@@@@@@@@@@@.\n");
printf(" *@@@@@@@@@@@@@= =@@@@@@@@@@@@@+ \n");
printf(" #@@@@@@@@@@@@@&+: :+@@@@@@@@@@@@@@# \n");
printf(" #@@@@@@@@@@@@@@@&*+=----=+#&@@@@@@@@@@@@@@@* \n");
printf(" +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+ \n");
printf(" :&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#: \n");
printf(" -#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#- \n");
printf(" :*@@@@@@@@@@@@@@@@@@@@@@@@@@@&+: \n");
printf(" :+#@@@@@@@@@@@@@@@@@@@@#+: \n");
printf(" :=+*#&@@@@@@&#*+-: \n");
free_info(info);
}

View File

@ -70,7 +70,7 @@ int main(){
if (!strcmp("version", argv[0])){
print_info();
}if (!strcmp("system", argv[0])){
}else if (!strcmp("system", argv[0])){
exit(0);
}else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) {
printf("-=[CoolPotShell Helper]=-\n");

View File

@ -1,3 +1,4 @@
/*
#include "../include/sb16.h"
#include "../include/io.h"
#include "../include/printf.h"
@ -8,83 +9,108 @@
static void *const DMA_BUF_ADDR1 = (void *)0x90000; // 不能跨越 64K 边界
static void *const DMA_BUF_ADDR2 = (void *)0x90000 + DMA_BUF_SIZE; // 不能跨越 64K 边界
struct sb16 sb;
#define STAT_OFF 0 // 未开启
#define STAT_WAITING 1 // 等待第一个缓冲区
#define STAT_PAUSED 2 // 已暂停
#define STAT_PLAYING 3 // 正在播放音频
#define STAT_CLOSING 4 // 正在等待播放完毕并关闭
void sb_exch_dmaaddr() {
char *addr = sb.addr1;
sb.addr1 = sb.addr2;
sb.addr2 = addr;
size_t size = sb.size1;
sb.size1 = sb.size2;
sb.size2 = size;
#if VSOUND_RWAPI
static void sb_exch_dmaaddr() {
char *addr = sb.addr1;
sb.addr1 = sb.addr2;
sb.addr2 = addr;
size_t size = sb.size1;
sb.size1 = sb.size2;
sb.size2 = size;
}
#endif
static void sb_out(uint8_t cmd) {
while (io_in8(SB_WRITE) & 128)
;
static void sb_send(uint8_t cmd) {
waitif(io_in8(SB_WRITE) & MASK(7));
io_out8(SB_WRITE, cmd);
}
void sb16_do_dma() {
// 设置采样率
sb_out(CMD_SOSR); // 44100 = 0xAC44
sb_out((SAMPLE_RATE >> 8) & 0xFF); // 0xAC
sb_out(SAMPLE_RATE & 0xFF); // 0x44
#if VSOUND_RWAPI
static void sb16_do_dma() {
size_t dmasize;
size_t len;
if (sb.auto_mode) {
dmasize = 2 * DMA_BUF_SIZE;
len = sb.depth == 8 ? DMA_BUF_SIZE : DMA_BUF_SIZE / 2;
len = sb.channels == 2 ? len / 2 : len;
if (sb.status != STAT_WAITING) return;
} else {
dmasize = sb.size2;
len = sb.depth == 8 ? sb.size2 : sb.size2 / 2;
len = sb.channels == 2 ? len / 2 : len;
}
dma_xfer(sb.channel, (uint32_t)(sb.addr2), sb.size2, 0);
if (sb.mode == MODE_MONO8) {
sb_out(CMD_SINGLE_OUT8);
sb_out(MODE_MONO8);
byte mode = (sb.auto_mode ? 16 : 0) | 0x48; // 0x48 为播放 0x44 为录音
dma_start(mode, sb.dma_channel, sb.addr2, dmasize, sb.depth == 16);
if (sb.auto_mode) {
sb_send(sb.depth == 8 ? CMD_AUTO_OUT8 : CMD_AUTO_OUT16);
} else {
sb_send(sb.depth == 8 ? CMD_SINGLE_OUT8 : CMD_SINGLE_OUT16);
}
sb_send(sb.mode);
sb_send((len - 1) & 0xff);
sb_send(((len - 1) >> 8) & 0xff);
}
#endif
#if VSOUND_RWAPI
static void sb16_send_buffer() {
if (sb.size1 == 0) return;
sb_exch_dmaaddr();
sb16_do_dma();
if (sb.status == STAT_WAITING) sb.status = STAT_PLAYING;
}
#endif
static void sb16_do_close() {
if (sb.auto_mode) {
sb_send(sb.depth == 8 ? 0xD9 : 0xDA);
} else {
sb_out(CMD_SINGLE_OUT16);
sb_out(MODE_STEREO16);
sb_send(CMD_OFF);
}
sb_out((sb.size2 - 1) & 0xFF);
sb_out(((sb.size2 - 1) >> 8) & 0xFF);
sb.use_task = null;
sb.status = STAT_OFF;
}
void sb16_do_close() {
sb_out(CMD_OFF); // 关闭声卡
sb.use_task = NULL;
}
static vsound_t snd;
void sb16_handler(registers_t *reg) {
io_in8(SB_INTR16);
uint8_t state = io_in8(SB_STATE);
io_cli();
io_in8(sb.depth == 16 ? SB_INTR16 : SB_STATE);
#if VSOUND_RWAPI
sb.size2 = 0;
if (sb.size1 > 0) {
sb_exch_dmaaddr();
sb16_do_dma();
}
io_cli();
if (sb.size1 == 0) sb.status = STAT_WAITING;
sb16_send_buffer();
#else
vsound_played(snd);
#endif
if (sb.status > 0) {
if (sb.status == STAT_CLOSING) {
sb16_do_close();
return;
}
}
void disable_sb16() {
sb.addr1 = DMA_BUF_ADDR1;
sb.addr2 = DMA_BUF_ADDR2;
sb.mode = MODE_STEREO16;
sb.channel = 5;
void sb16_init() {
sb.use_task = NULL;
sb.size1 = 0;
sb.size2 = 0;
sb.status = 0;
register_interrupt_handler(SB16_IRQ + 0x20, (uint32_t)sb16_handler);
sb.status = STAT_OFF;
register_interrupt_handler(SB16_IRQ + 0x20, sb16_handler);
}
static void sb_reset() {
io_out8(SB_RESET, 1);
sleep(10);
auto oldcnt = timerctl.count;
waitif(timerctl.count <= oldcnt + 10);
io_out8(SB_RESET, 0);
uint8_t state = io_in8(SB_READ);
logkf("sb16 reset state 0x%x\n", state);
}
static void sb_intr_irq() {
@ -96,58 +122,159 @@ static void sb_intr_irq() {
}
}
static void sb_turn(bool on) {
if (on)
sb_out(CMD_ON);
else
sb_out(CMD_OFF);
static void sb16_set_samplerate(uint16_t rate) {
sb_send(CMD_SOSR);
sb_send(rate >> 8);
sb_send(rate & 0xff);
}
static uint32_t sb_time_constant(uint8_t channels, uint16_t sample) {
return 65536 - (256000000 / (channels * sample));
}
void sb16_set_volume(uint8_t level) {
logkf("set sb16 volume to %d/255\n", level);
static void sb16_set_volume(double volume) {
volume = max(0, min(volume, 1));
klogd("set sb16 volume to %d%%", (int)(volume * 100));
io_out8(SB_MIXER, 0x22);
io_out8(SB_MIXER_DATA, level);
io_out8(SB_MIXER_DATA, volume * 255);
}
void sb16_open() {
while (sb.use_task) {}
io_cli();
extern bool is_vbox;
static int sb16_open(vsound_t vsound) {
uint16_t fmt = vsound->fmt;
uint16_t channels = vsound->channels;
uint32_t rate = vsound->rate;
double volume = vsound->volume;
sb.use_task = get_current();
io_sti();
sb_reset(); // 重置 DSP
sb_intr_irq(); // 设置中断
sb_out(CMD_ON); // 打开声卡
sb.mode = MODE_MONO8;
sb.channel = 1;
sb.size1 = 0;
sb.size2 = 0;
sb.status = 0;
sb_reset(); // 重置 DSP
sb_intr_irq(); // 设置中断
sb_send(CMD_ON); // 打开声卡
// sb.mode = MODE_STEREO16;
// sb.channel = 5;
if (fmt == SOUND_FMT_S16 || fmt == SOUND_FMT_U16) {
sb.depth = 16;
sb.dma_channel = 5;
} else if (fmt == SOUND_FMT_U8 || fmt == SOUND_FMT_S8) {
sb.depth = 8;
sb.dma_channel = 1;
}
if (channels == 1) {
sb.mode = (fmt == SOUND_FMT_S16 || fmt == SOUND_FMT_S8) ? MODE_SMONO : MODE_UMONO;
} else {
sb.mode = (fmt == SOUND_FMT_S16 || fmt == SOUND_FMT_S8) ? MODE_SSTEREO : MODE_USTEREO;
}
sb.status = STAT_WAITING;
#if VSOUND_RWAPI
sb.addr1 = DMA_BUF_ADDR1;
sb.addr2 = DMA_BUF_ADDR2;
sb.size1 = 0;
sb.size2 = 0;
#endif
sb.channels = channels;
sb.auto_mode = is_vbox ? true : false;
sb16_set_samplerate(rate);
sb16_set_volume(volume);
return 0;
}
void sb16_close() {
sb.status = 1;
if (sb.size2 > 0) return;
sb16_do_close();
static void sb16_close(vsound_t vsound) {
if (sb.status == STAT_PLAYING) {
sb.status = STAT_CLOSING;
} else {
sb16_do_close();
}
}
int sb16_write(char *data, size_t size) {
while (sb.size1) {}
#if VSOUND_RWAPI
static int sb16_write(vsound_t vsound, const void *data, size_t len) {
size_t size = len * vsound->settings.bytes_per_sample;
while (size > 0) {
waitif(sb.size1 == DMA_BUF_SIZE);
asm_cli;
size_t nwrite = min(size, DMA_BUF_SIZE - sb.size1);
memcpy(sb.addr1 + sb.size1, data, nwrite);
sb.size1 += nwrite;
data += nwrite;
size -= nwrite;
asm_sti;
if (sb.auto_mode) {
if (sb.status == STAT_WAITING && sb.size1 == DMA_BUF_SIZE) sb16_send_buffer();
} else {
if (sb.status == STAT_WAITING) sb16_send_buffer();
}
}
return 0;
}
#endif
memcpy(sb.addr1, data, size);
sb.size1 = size;
#if !VSOUND_RWAPI
static int sb16_start_dma(vsound_t vsound, void *addr) {
size_t dmasize;
size_t len;
if (sb.auto_mode) {
dmasize = 2 * DMA_BUF_SIZE;
len = DMA_BUF_SIZE / vsound->bytes_per_sample;
if (sb.status != STAT_WAITING) return 0;
} else {
dmasize = DMA_BUF_SIZE;
len = DMA_BUF_SIZE / vsound->bytes_per_sample;
}
if (sb.size2 > 0) return size;
byte mode = (sb.auto_mode ? 16 : 0) | 0x48; // 0x48 为播放 0x44 为录音
dma_start(mode, sb.dma_channel, addr, dmasize, sb.depth == 16);
if (sb.auto_mode) {
sb_send(sb.depth == 8 ? CMD_AUTO_OUT8 : CMD_AUTO_OUT16);
} else {
sb_send(sb.depth == 8 ? CMD_SINGLE_OUT8 : CMD_SINGLE_OUT16);
}
sb_send(sb.mode);
sb_exch_dmaaddr();
sb16_do_dma();
sb_send((len - 1) & 0xff);
sb_send(((len - 1) >> 8) & 0xff);
return size;
}
if (sb.status == STAT_WAITING) sb.status = STAT_PLAYING;
return 0;
}
#endif
static struct vsound vsound = {
.is_output = true,
#if VSOUND_RWAPI
.is_rwmode = true,
#endif
.name = "sb16",
.open = sb16_open,
.close = sb16_close,
#if VSOUND_RWAPI
.write = sb16_write,
#else
.start_dma = sb16_start_dma,
.bufsize = DMA_BUF_SIZE,
#endif
};
static const i16 fmts[] = {
SOUND_FMT_S8, SOUND_FMT_U8, SOUND_FMT_S16, SOUND_FMT_U16, -1,
};
static const i32 rates[] = {
8000, 11025, 16000, 22050, 24000, 32000, 44100, 47250, 48000, 50000, -1,
};
void sb16_regist() {
snd = &vsound;
if (!vsound_regist(snd)) {
klogw("注册 sb16 失败");
return;
}
vsound_set_supported_fmts(snd, fmts, -1);
vsound_set_supported_rates(snd, rates, -1);
vsound_set_supported_ch(snd, 1);
vsound_set_supported_ch(snd, 2);
#if !VSOUND_RWAPI
vsound_addbuf(snd, DMA_BUF_ADDR1);
vsound_addbuf(snd, DMA_BUF_ADDR2);
#endif
}
*/

View File

@ -31,53 +31,35 @@
#define CMD_RP16 0xD6 // Resume playback of 16 bit channel
#define CMD_VERSION 0xE1 // Turn speaker off
#define MODE_MONO8 0x00
#define MODE_STEREO8 0x20
#define MODE_MONO16 0x10
#define MODE_STEREO16 0x30
#define MODE_SMONO (0b01 << 4)
#define MODE_SSTEREO (0b11 << 4)
#define MODE_UMONO (0b00 << 4)
#define MODE_USTEREO (0b10 << 4)
#define STATUS_READ 0x80 // read buffer status
#define STATUS_WRITE 0x80 // write buffer status
#define DMA_BUF_SIZE 0x8000 // 缓冲区长度
#define SAMPLE_RATE 44100 // 采样率
#define SB16_IRQ 5
#define DMA_BUF_SIZE 4096 // 缓冲区长度
#define SB16_IRQ 5
#include "task.h"
#include "common.h"
#include "isr.h"
struct WAV16_HEADER {
char riff[4];
int size;
char wave[4];
char fmt[4];
int fmt_size;
short format;
short channel;
int sample_rate;
int byte_per_sec;
} __attribute__((packed));
struct sb16 {
struct task_struct *use_task;
int status;
char *addr1; // DMA 地址
volatile size_t size1; //
char *addr2; // DMA 地址
volatile size_t size2; //
uint8_t mode; // 模式
uint8_t channel; // DMA 通道
};
void sb16_handler(registers_t *reg);
void sb_exch_dmaaddr();
void sb16_do_dma();
void sb16_do_close();
void disable_sb16();
void sb16_close();
int sb16_write(char *data, size_t size);
void sb16_open();
void sb16_set_volume(uint8_t level);
static struct {
struct task_struct *use_task; //
int status; //
bool auto_mode; //
#if VSOUND_RWAPI
void *volatile addr1; // DMA 地址
volatile size_t size1; //
void *volatile addr2; // DMA 地址
volatile size_t size2; //
#endif
uint8_t mode; // 模式
uint8_t dma_channel; // DMA 通道
uint8_t depth; // 采样深度
int channels; // 声道数
} sb;
#endif

View File

@ -73,6 +73,7 @@ int check_task(int *pid){
}
int check_task_usershell(int *pid){
while (1) asm("hlt");
struct task_struct *shell = found_task_pid(*pid);
while (1){
if(shell->state == TASK_DEATH){
@ -153,7 +154,6 @@ void kernel_main(multiboot_t *multiboot) {
}
init_eh();
klogf(true,"Kernel load done!\n");
kernel_thread(sound_test,NULL,"Sound");
io_sti();

View File

@ -29,7 +29,6 @@ static char syscall_getch(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,ui
static void syscall_exit(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
task_kill(get_current()->pid);
//printf("PID[%d] exit code: %d",get_current()->pid,ebx);
}
static void* syscall_malloc(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
@ -84,13 +83,13 @@ struct sysinfo{
static void* syscall_sysinfo(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){
struct sysinfo *info = (struct sysinfo *) user_alloc(get_current(), sizeof(struct sysinfo));
cpu_t *cpu = get_cpuid();
char *os_name = user_alloc(get_current(), strlen(OS_NAME));
char *kernel = user_alloc(get_current(), strlen(OS_NAME));
char *cpu_vendor = user_alloc(get_current(), strlen(cpu->vendor));
char *cpu_name = user_alloc(get_current(), strlen(cpu->model_name));
char *os_name = (char *)user_alloc(get_current(), strlen(OS_NAME));
char *kernel = (char *)user_alloc(get_current(), strlen(KERNEL_NAME));
memcpy(os_name,OS_NAME, 40);
memcpy(kernel,KERNEL_NAME, 40);
char *cpu_vendor = (char *)user_alloc(get_current(), strlen(cpu->vendor));
char *cpu_name = (char *)user_alloc(get_current(), strlen(cpu->model_name));
memcpy(os_name,OS_NAME, strlen(OS_NAME));
memcpy(kernel,KERNEL_NAME, strlen(KERNEL_NAME));
memcpy(cpu_vendor,cpu->vendor, strlen(cpu->vendor));
memcpy(cpu_name,cpu->model_name, strlen(cpu->model_name));
@ -111,6 +110,8 @@ static void* syscall_sysinfo(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi
info->min = get_min();
info->sec = get_sec();
kfree(cpu);
return info;
}
@ -132,6 +133,7 @@ void *sycall_handlers[MAX_SYSCALLS] = {
typedef size_t (*syscall_t)(size_t, size_t, size_t, size_t, size_t);
size_t syscall() {
io_cli();
volatile size_t eax, ebx, ecx, edx, esi, edi;
asm("mov %%eax, %0\n\t" : "=r"(eax));
asm("mov %%ebx, %0\n\t" : "=r"(ebx));

View File

@ -66,20 +66,6 @@ static uint8_t gen(int t) {
}
void sound_test() {
logk("sound test has been started\n");
F = g(0);
G = g(T);
const int total = T + ((128 - F) + (128 - G)) * K;
sb16_open();
sb16_set_volume(128);
uint8_t *buffer = kmalloc(buffer_len);
for (int offset = 0;; offset++) {
if (offset * buffer_len >= total) break;
for (int i = 0; i < buffer_len; i++)
buffer[i] = gen(i + offset * buffer_len);
sb16_write(buffer, buffer_len);
}
sb16_close();
kfree(buffer);
}