From: <ga...@wi...> - 2001-11-24 22:01:22
|
Has anyone sucessfully swapped out the 16MB memory chip that the dreamcast comes with for a larger chip? Gareth -- "Apparently if you play the Windows NT CD backwards you hear satanic messages" "You think that's bad, if you play it forwards it installs Windows NT!" ------------------------------------------------------------------------------ Gareth J. Greenaway ga...@wi... |
From: Adrian M. <ad...@mc...> - 2001-11-25 01:05:06
|
My work on building a sound driver for LinuxDC continues ... but I have a problem which someone on the list might be able to help with. Essentially, I need an application for the DC which will attempt to play some sound. I have been trying use PRBOOM, but it seems to have difficulties with the framebuffer (?). I have had PRBOOM work before on the DC but more by hit an miss than design. Currently PRBOOM opens the sound drivers but then promptly shuts down reporting that it cannot set the display to 320 x 200. All the right debug messages appear on screen indicating that the open and release methods on the driver are opened and closed in the right order and that all the memory_requests and memory_releases work, but nothing is around long enough to be seriously tested. So: do you have such an app, or can you give me a fireproof way of getting PRBOOM to run? Thanks Adrian |
From: M. R. B. <mr...@0x...> - 2001-11-25 02:56:47
|
* Adrian McMenamin <ad...@mc...> on Sun, Nov 25, 2001: >=20 > So: do you have such an app, or can you give me a fireproof way of gettin= g=20 > PRBOOM to run? >=20 $ cat /dev/urandom > /dev/dsp Should produce static if it works. M. R. |
From: Adrian M. <ad...@mc...> - 2001-12-02 16:25:09
|
Well, maybe I should be writing ARM code after all - but I'm still going to give the SH4 stuff one more try and I have a question which I wonder if someone might help me with. In the dsp write the code currently does this... static ssize_t aica_audio_do_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { aica_dev_t *devc=file->private_data; //really want to write? if (!(file->f_mode & FMODE_WRITE)) return -EINVAL; //now output this to the selected channel //fill a chunk of the sound memory with the contents of the buffer aica_halt_channel(devc->channel); //halt anything playing there already int offset = 0xf000; if (copy_from_user((void*)(0xa0800000 + offset), (const void*) buffer, count)) { DEBGM("Failed to copy memory bufferfrom user space\n"); return -EFAULT; } . . . . ...........Lots of code.......... . return count; } Now, is it right to just copy a lump of memory over from user space in this way? I haven't specifically allocated a buffer inside the sound RAM area - just claimed it for the kernel when initiating the module and assumed that it's there - the function doesn't fail in the sense that the -EFAULT error is never reported, but does that mean it has actually worked? Should I be allocating a buffer first and copying the data from user space into that? Perhaps I am just clutching at straws. |
From: Adrian M. <ad...@mc...> - 2001-12-02 18:00:46
|
On Sunday 02 Dec 2001 4:18 pm, Adrian McMenamin wrote: > Well, maybe I should be writing ARM code after all - but I'm still going to > give the SH4 stuff one more try and I have a question which I wonder if > someone might help me with. > > In the dsp write the code currently does this... > > static ssize_t aica_audio_do_write(struct file *file, > const char *buffer, > size_t count, > loff_t *ppos) > { > > aica_dev_t *devc=file->private_data; > > //really want to write? > if (!(file->f_mode & FMODE_WRITE)) return -EINVAL; > > > //now output this to the selected channel > > //fill a chunk of the sound memory with the contents of the buffer > aica_halt_channel(devc->channel); //halt anything playing there already > int offset = 0xf000; > if (copy_from_user((void*)(0xa0800000 + offset), (const void*) buffer, > count)) > { > DEBGM("Failed to copy memory bufferfrom user space\n"); > return -EFAULT; > } > > . > . > . > . > ...........Lots of code.......... > . > > > return count; > > } > > Now, is it right to just copy a lump of memory over from user space in this > way? > > I haven't specifically allocated a buffer inside the sound RAM area - just > claimed it for the kernel when initiating the module and assumed that it's > there - the function doesn't fail in the sense that the -EFAULT error is > never reported, but does that mean it has actually worked? > > Should I be allocating a buffer first and copying the data from user space > into that? > > Perhaps I am just clutching at straws. > My own tests suggest this to be the case :-< |
From: M. R. B. <mr...@0x...> - 2001-12-02 19:05:34
|
* Adrian McMenamin <ad...@mc...> on Sun, Dec 02, 2001: >=20 > Now, is it right to just copy a lump of memory over from user space in th= is=20 > way? >=20 Well even if it was ok (I don't know) semantically, you can't do it realistically for the AICA. Remember the discussion on dcdev? You can only copy so much data to AICA RAM at once - if you don't wait for the FIFO to be clear then you'll crash the AICA. > I haven't specifically allocated a buffer inside the sound RAM area - jus= t=20 > claimed it for the kernel when initiating the module and assumed that it'= s=20 > there - the function doesn't fail in the sense that the -EFAULT error is= =20 > never reported, but does that mean it has actually worked? >=20 > Should I be allocating a buffer first and copying the data from user spac= e=20 > into that? >=20 Damn, I need time :P. Check out the latest KOS which (apparently) has AICA DMA working. You want to use DMA. You have to use DMA. It's DMA or die =2E.. ok maybe that's too much. But that's the only way you'll effectively get anything to AICA RAM without choking on the FIFO. I still have to sit down and write the register test to see if it's feasible to play with the AICA regs directly from the SH4. Or you could :P. > Perhaps I am just clutching at straws. >=20 What you need is a AICA test program. It doesn't even have to be kernel related, and you can provide your own inX() outX() routines that treat the AICA registers as latches and checks *every* value you get back from the AICA. I still believe you can play with AICA registers from the SH4, take a look at this: =46rom arch/sh/kernel/rtc-aica.c: /* The AICA RTC is represented by a 32-bit seconds counter stored in 2 * 16-bit registers.*/ #define AICA_RTC_SECS_H 0xa0710000 #define AICA_RTC_SECS_L 0xa0710004 /** * aica_rtc_gettimeofday - Get the time from the AICA RTC * @tv: pointer to resulting timeval * * Grabs the current RTC seconds counter and adjusts it to the Unix * Epoch. */ void aica_rtc_gettimeofday(struct timeval *tv) { unsigned long val1, val2; do { val1 =3D ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); val2 =3D ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); } while (val1 !=3D val2); tv->tv_sec =3D val1 - TWENTY_YEARS; /* Can't get microseconds with just a seconds counter. */ tv->tv_usec =3D 0; } Now, you see how I'm grabbing those registers? In your test program (or your kernel driver), write a generic routine that does just that. You may end up with valid values after all. The aica_rtc_settimeofday() is basically the same, except at the top of the while loop, there are ctrl_outl() statements that write the register value. You could even throw the FIFO check in there just to be on the safe side. Let's prove those dcdev'rs wrong :P. Let me know what you come up with, and I'll try to work on something later. Hope this helps, M. R. |
From: Adrian M. <ad...@mc...> - 2001-12-02 19:36:06
|
On Sunday 02 Dec 2001 7:05 pm, M. R. Brown wrote: > * Adrian McMenamin <ad...@mc...> on Sun, Dec 02, 2001: > > Now, is it right to just copy a lump of memory over from user space in > > this way? > > Well even if it was ok (I don't know) semantically, you can't do it > realistically for the AICA. Remember the discussion on dcdev? You can > only copy so much data to AICA RAM at once - if you don't wait for the FIFO > to be clear then you'll crash the AICA. > That may be the problem - as the memory allocation now apears to work (at least a read of the memory returns that it contains the same data that was written). > > I haven't specifically allocated a buffer inside the sound RAM area - > > just claimed it for the kernel when initiating the module and assumed > > that it's there - the function doesn't fail in the sense that the -EFAULT > > error is never reported, but does that mean it has actually worked? > > > > Should I be allocating a buffer first and copying the data from user > > space into that? > > Damn, I need time :P. Check out the latest KOS which (apparently) has AICA > DMA working. You want to use DMA. You have to use DMA. It's DMA or die > ... ok maybe that's too much. But that's the only way you'll effectively > get anything to AICA RAM without choking on the FIFO. > I'd have to write my own DMA routines (I think) as the kernel supported ones crash the SH4 kernel or rather cause input to freeze up - far too big a job for me. > I still have to sit down and write the register test to see if it's > feasible to play with the AICA regs directly from the SH4. Or you could > > :P. > : > > Perhaps I am just clutching at straws. > > What you need is a AICA test program. It doesn't even have to be kernel > related, and you can provide your own inX() outX() routines that treat the > AICA registers as latches and checks *every* value you get back from the > AICA. I still believe you can play with AICA registers from the SH4, take > a look at this: > > From arch/sh/kernel/rtc-aica.c: > > /* The AICA RTC is represented by a 32-bit seconds counter stored in 2 > * 16-bit registers.*/ > #define AICA_RTC_SECS_H 0xa0710000 > #define AICA_RTC_SECS_L 0xa0710004 > > /** > * aica_rtc_gettimeofday - Get the time from the AICA RTC > * @tv: pointer to resulting timeval > * > * Grabs the current RTC seconds counter and adjusts it to the Unix > * Epoch. > */ > void aica_rtc_gettimeofday(struct timeval *tv) { > unsigned long val1, val2; > > do { > val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | > (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); > val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | > (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); > } while (val1 != val2); > > tv->tv_sec = val1 - TWENTY_YEARS; > > /* Can't get microseconds with just a seconds counter. */ > tv->tv_usec = 0; > } > > > Now, you see how I'm grabbing those registers? Yes, okay but I am not exactly sure what the point you are making is. Simple test routines I've put in the SH4 code today show that the registers report that their contents after writing agree with the value that is meant to be written to them. In your test program (or > your kernel driver), write a generic routine that does just that. You may > end up with valid values after all. > > The aica_rtc_settimeofday() is basically the same, except at the top of the > while loop, there are ctrl_outl() statements that write the register value. > You could even throw the FIFO check in there just to be on the safe side. > I need to know more about the FIFO I thin - is it in the CPU manual? > Let's prove those dcdev'rs wrong :P. Let me know what you come up with, > and I'll try to work on something later. > > Hope this helps, > > M. R. |
From: Paul M. <pm...@mv...> - 2001-12-02 19:38:23
|
On Sun, Dec 02, 2001 at 01:05:23PM -0600, M. R. Brown wrote: > Damn, I need time :P. Check out the latest KOS which (apparently) has AI= CA > DMA working. You want to use DMA. You have to use DMA. It's DMA or die > ... ok maybe that's too much. But that's the only way you'll effectively > get anything to AICA RAM without choking on the FIFO. >=20 Er, side stepping the FIFO through DMA doesn't sound like that good of a solution either. DMA is definately the optimal way to go for AICA access, b= ut it might still prove to be useful to have a non-DMA fallback that waits on = the FIFO for its reads (especially for debugging when things go horribly wrong). If the FIFO is slow in dealing with, there's likely a good reason for it.. doing DMA directly without any kind of flow control might also cause you to kill the AICA. [snip] > void aica_rtc_gettimeofday(struct timeval *tv) { > unsigned long val1, val2; >=20 > do { > val1 =3D ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | > (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); > val2 =3D ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | > (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); > } while (val1 !=3D val2); [snip] > } >=20 The other thing to consider (as I've told you on IRC), the AICA is likely n= ot too responsive.. and expecting it to be will likely end up shooting you in = the foot. Perhaps something more along the lines of waiting for a brief duration of time after a read (mdelay(5) perhaps?), and doing the reads with interru= pts disabled might prove to yield more consistent data without the need to do a nasty read-twice and compare hack. Regards, --=20 Paul Mundt <pm...@mv...> MontaVista Software, Inc. |
From: M. R. B. <mr...@0x...> - 2001-12-02 20:06:41
|
* Paul Mundt <pm...@mv...> on Sun, Dec 02, 2001: >=20 > If the FIFO is slow in dealing with, there's likely a good reason for it.. > doing DMA directly without any kind of flow control might also cause you = to > kill the AICA. >=20 I have to see how Dan Potter does AICA DMA in KOS and review the notes from my reverse-engineering sessions. I think it operates like any other DMA on the DC's G2 bus .. let's hope so. Whoops! Just grabbed kos from CVS and yeah, it uses bitmaster's original AICA DMA example, so it's normal G2 DMA, nothing special. > The other thing to consider (as I've told you on IRC), the AICA is likely= not > too responsive.. and expecting it to be will likely end up shooting you i= n the > foot. Perhaps something more along the lines of waiting for a brief durat= ion > of time after a read (mdelay(5) perhaps?), and doing the reads with inter= rupts > disabled might prove to yield more consistent data without the need to do= a > nasty read-twice and compare hack. >=20 Yeah, I think the tests that people have done on the AICA haven't been that intensive ... if something broke that passed it off as broken instead of exploring work arounds. A couple of us need to sit down and really plug the fscker :P. M. R. |
From: Adrian M. <ad...@mc...> - 2001-12-03 00:00:27
|
Various fixes I have made still don't produce any sound. I think we can be sure that it is possible to set the register values in SH4 land - but the key issue seems to be finding some code for the ARM to run. To tell the truth I had been working on the assumption that the ARM had some sort of firmware code that allowed it to do different things - but I know that is now not true. I made this assumption because Dan Potter's code doesn't appear to do anything but poke the registers. But KOS also appears to have a little bit of ARM7 assembler - crt0.s My knowledge of ARM 7 assembler is zero - but this code seems to me to be the bit that resides at ARM address 0 It compiles to a 1.1k bit of code. What do people think? Is this the holy grail (suitably modified, of course). # Adapted from Marcus' AICA example among a few other sources =) .text .globl arm_main .globl timer .globl jps # Exception vectors b start b undef b softint b pref_abort b data_abort b rsrvd b irq # FIQ code adapted from the Marcus AICA example fiq: # Save regs #stmdb sp!, {r0-r14} # Grab interrupt type (store as parameter) ldr r8,intreq ldr r9,[r8] and r9,r9,#7 cmp r9,#2 bne fiq_done # Type 2 is timer interrupt. Increment timer variable. adr r8,timer ldr r9,[r8] add r9,r9,#1 str r9,[r8] # Request a new timer interrupt. We'll calculate the number # put in here based on the "jps" (jiffies per second). ldr r8, timer_control mov r9,#256-(44100/4410) # ldr r9,jps str r9,[r8,#0x10] mov r9,#0x40 str r9,[r8,#0x24] b fiq_done # Return from interrupt fiq_done: # Clear interrupt ldr r8,intclr mov r9,#1 str r9,[r8] str r9,[r8] str r9,[r8] str r9,[r8] # Restore regs and return #ldmdb sp!, {r0-r14} subs pc,r14,#4 intreq: .long 0x00802d00 intclr: .long 0x00802d04 timer_control: .long 0x00802880 timer: .long 0 jps: .long 256-(44100/1000) start: # Setup a basic stack, disable IRQ, enable FIQ mov sp,#0xb000 mrs r10,CPSR orr r10,r10,#0x80 bic r10,r10,#0x40 msr CPSR_all,r10 # Call the main for the SPU bl arm_main # Loop infinitely if we get here here: b here # Handlers we don't bother to catch undef: softint: mov pc,r14 pref_abort: data_abort: irq: rsrvd: sub pc,r14,#4 |
From: Adrian M. <ad...@mc...> - 2001-12-04 23:58:59
|
On Sunday 02 Dec 2001 11:49 pm, Adrian McMenamin wrote: > Various fixes I have made still don't produce any sound. I think I am finally going to admit defeat and write some ARM code. The hacked version of the assembler I used doesn't work - presumably because it simply locks the ARM in an endless loop. The issue seems to be what the ARM processor is doing rather than any difficulty of writing to the ARM registers - if its stuck in an endless loop with interrupts off then I don't suppose it matters what values you poke its registers with :-> I can see how Dan Potter manges his IPC on the simple stuff and I'll simply copy that (or rather produce something similar to fit in with the OSS interface). It should produce a working driver of sorts in a day ot two. It's not elegant - DP's code simply polls for any new commands, but as the ARM is not important in terms of executing anything in either user or kernel space, we can afford to be I think. Assuming nobody leaps up to tell me I've got this all wrong I will start work tomorrow. Will let you know how it goes. Adrian |