This patchset is something I've been working on for a while and started off with the aim of getting rid of the "dma-alloc" console warnings whilst booting *BSD images on PPC, but ended up as a full implementation for SPARC32/SPARC64 and PPC.
The patchset is fairly straightfoward: the first few patches rework the SPARC32 DVMA functions to make them usable from Forth, whilst patch 8 adds a missing D-cache flush for PPC which could certainly do with another set of eyes.
The remainder of the patches add PPC and SPARC64 support before adding in the complete "dma-*" $call-parent chains to enable devices to call the DMA functions as indicated in the IEEE-1275 specification and various FCode examples found around the net.
Finally the last 2 patches switch the esp SCSI driver over to use the IEEE-1275 Forth words instead of calling the low-level C functions directly.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
Mark Cave-Ayland (15): dma: add defers for the dma-* words SPARC32: rename dvma_alloc()'s ba variable to iova SPARC32: allocate contiguous physical memory for DVMA SPARC32: implement dvma_map_in() for DMA IOVA to phys translation SPARC32: move pgtsrmmu.h from arch/sparc32 to include/arch/sparc32 SPARC32: implement dvma_sync() function for synchronising DMA memory SPARC32: implement dma-* words PPC: add flush_dcache_range() to start.S PPC: implement dma-* words SPARC64: implement dma-* words macio: add missing REGISTER_NODE for New World macio devices pci: add dma-* call-parent chain to all PCI devices and bridges sbus: add dma-* call-parent chain to all PCI devices and bridges esp: switch creation of esp device over to use new-device esp: switch over to using dma-alloc/dma-map-in
arch/ppc/qemu/init.c | 35 +++++++ arch/ppc/qemu/kernel.h | 1 + arch/ppc/qemu/start.S | 21 ++++ arch/ppc/qemu/tree.fs | 40 ++++++++ arch/sparc32/lib.c | 2 +- arch/sparc32/ofmem_sparc32.c | 2 +- arch/sparc32/openbios.c | 47 ++++++++- arch/sparc32/tree.fs | 56 +++++++++++ arch/sparc64/openbios.c | 40 ++++++++ arch/sparc64/tree.fs | 47 +++++++++ drivers/esp.c | 159 ++++++++++++++++++++---------- drivers/ide.c | 40 ++++++++ drivers/iommu.c | 95 +++++++++++++++--- drivers/macio.c | 36 +++++++ drivers/pci.c | 40 ++++++++ forth/device/other.fs | 8 +- forth/device/table.fs | 2 +- forth/util/util.fs | 9 ++ {arch => include/arch}/sparc32/pgtsrmmu.h | 0 include/drivers/drivers.h | 4 +- packages/disk-label.fs | 39 ++++++++ 21 files changed, 646 insertions(+), 77 deletions(-) rename {arch => include/arch}/sparc32/pgtsrmmu.h (100%)
Whilst there is an existing implementation of dma-alloc, it is currently unused so we can make this change now.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- forth/device/other.fs | 8 +++++--- forth/device/table.fs | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/forth/device/other.fs b/forth/device/other.fs index b390073..1bed9b8 100644 --- a/forth/device/other.fs +++ b/forth/device/other.fs @@ -228,6 +228,8 @@ variable obp-ticks strdup my-self >in.arguments 2! ;
-: dma-alloc - s" dma-alloc" $call-parent - ; +defer (dma-alloc) +defer (dma-free) +defer (dma-map-in) +defer (dma-map-out) +defer (dma-sync) diff --git a/forth/device/table.fs b/forth/device/table.fs index 5c58f2d..04d22c8 100644 --- a/forth/device/table.fs +++ b/forth/device/table.fs @@ -247,7 +247,7 @@ create fcode-master-table ['], 4-byte-id ['], end1 ['], reserved-fcode - ['], dma-alloc + ['], (dma-alloc) ['], my-address ['], my-space ['], memmap
This makes it clearer that we are handling a virtual IO address.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/iommu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu.c b/drivers/iommu.c index cd9a64b..be486c0 100644 --- a/drivers/iommu.c +++ b/drivers/iommu.c @@ -45,7 +45,7 @@ void * dvma_alloc(int size, unsigned int *pphys) { void *va; - unsigned int pa, ba; + unsigned int pa, iova; unsigned int npages; unsigned int mva, mpa; unsigned int i; @@ -58,8 +58,8 @@ dvma_alloc(int size, unsigned int *pphys) if (ret != 0) return NULL;
- ba = (unsigned int)mem_alloc(&cdvmem, npages * PAGE_SIZE, PAGE_SIZE); - if (ba == 0) + iova = (unsigned int)mem_alloc(&cdvmem, npages * PAGE_SIZE, PAGE_SIZE); + if (iova == 0) return NULL;
pa = (unsigned int)va2pa((unsigned long)va); @@ -75,13 +75,13 @@ dvma_alloc(int size, unsigned int *pphys) * Map into IOMMU page table. */ mpa = (unsigned int) pa; - iopte = &t->page_table[(ba - t->plow) / PAGE_SIZE]; + iopte = &t->page_table[(iova - t->plow) / PAGE_SIZE]; for (i = 0; i < npages; i++) { *iopte++ = MKIOPTE(mpa); mpa += PAGE_SIZE; }
- *pphys = ba; + *pphys = iova;
return va; }
Currently we dynamically allocate physical memory for DVMA as required, however that makes mapping between IOVA and physical addresses almost impossible since the resulting regions are not contiguous.
Resolve this by allocating a contiguous physical memory block that we can use to easily map between IOVA and physical addresses.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/iommu.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/iommu.c b/drivers/iommu.c index be486c0..0bf742f 100644 --- a/drivers/iommu.c +++ b/drivers/iommu.c @@ -25,6 +25,7 @@ struct iommu { struct iommu_regs *regs; unsigned int *page_table; unsigned long plow; /* Base bus address */ + unsigned long pphys; /* Base phys address */ };
static struct iommu ciommu; @@ -51,18 +52,14 @@ dvma_alloc(int size, unsigned int *pphys) unsigned int i; unsigned int *iopte; struct iommu *t = &ciommu; - int ret;
npages = (size + (PAGE_SIZE-1)) / PAGE_SIZE; - ret = ofmem_posix_memalign(&va, npages * PAGE_SIZE, PAGE_SIZE); - if (ret != 0) - return NULL; - iova = (unsigned int)mem_alloc(&cdvmem, npages * PAGE_SIZE, PAGE_SIZE); if (iova == 0) return NULL;
- pa = (unsigned int)va2pa((unsigned long)va); + pa = t->pphys + (iova - t->plow); + va = (void *)pa2va((unsigned long)pa);
/* * Change page attributes in MMU to uncached. @@ -86,6 +83,8 @@ dvma_alloc(int size, unsigned int *pphys) return va; }
+#define DVMA_SIZE 0x4000 + /* * Initialize IOMMU * This looks like initialization of CPU MMU but @@ -94,7 +93,7 @@ dvma_alloc(int size, unsigned int *pphys) static struct iommu_regs * iommu_init(struct iommu *t, uint64_t base) { - unsigned int *ptab; + unsigned int *ptab, pva; int ptsize; #ifdef CONFIG_DEBUG_IOMMU unsigned int impl, vers; @@ -145,7 +144,13 @@ iommu_init(struct iommu *t, uint64_t base) DPRINTF("IOMMU: impl %d vers %d page table at 0x%p (pa 0x%x) of size %d bytes\n", impl, vers, t->page_table, tmp, ptsize);
- mem_init(&cdvmem, (char*)t->plow, (char *)0xfffff000); + mem_init(&cdvmem, (char*)t->plow, (char *)(t->plow + DVMA_SIZE)); + ret = ofmem_posix_memalign((void *)&pva, DVMA_SIZE, PAGE_SIZE); + if (ret != 0) { + DPRINTF("Cannot allocate IOMMU phys size [0x%x]\n", DVMA_SIZE); + for (;;) { } + } + t->pphys = va2pa(pva); return regs; }
Rather than have dvma_alloc() store the result of the physical translation in the specified location, use the fact that we now have contiguous physical DMA memory to implement dvma_map_in() to perform the translation separately.
This allows us to remove the pointer to the physical address parameter to dvma_alloc() and instead perform the translation in esp.c by calling dvma_map_in() separately.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/esp.c | 3 ++- drivers/iommu.c | 17 ++++++++++++++--- include/drivers/drivers.h | 3 ++- 3 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/esp.c b/drivers/esp.c index a4d6ef4..44b2096 100644 --- a/drivers/esp.c +++ b/drivers/esp.c @@ -490,7 +490,8 @@ ob_esp_init(unsigned int slot, uint64_t base, unsigned long espoffset, return -1; }
- esp->buffer = (void *)dvma_alloc(BUFSIZE, &esp->buffer_dvma); + esp->buffer = (void *)dvma_alloc(BUFSIZE); + esp->buffer_dvma = dvma_map_in(esp->buffer); if (!esp->buffer || !esp->buffer_dvma) { DPRINTF("Can't get a DVMA buffer\n"); return -1; diff --git a/drivers/iommu.c b/drivers/iommu.c index 0bf742f..b8ec09e 100644 --- a/drivers/iommu.c +++ b/drivers/iommu.c @@ -43,7 +43,7 @@ iommu_invalidate(struct iommu_regs *iregs) * BTW, we were not going to give away anonymous storage, were we not? */ void * -dvma_alloc(int size, unsigned int *pphys) +dvma_alloc(int size) { void *va; unsigned int pa, iova; @@ -78,11 +78,22 @@ dvma_alloc(int size, unsigned int *pphys) mpa += PAGE_SIZE; }
- *pphys = iova; - return va; }
+unsigned int +dvma_map_in(unsigned char *va) +{ + /* Convert from VA to IOVA */ + unsigned int pa, iova; + struct iommu *t = &ciommu; + + pa = va2pa((unsigned int)va); + iova = t->plow + (pa - t->pphys); + + return iova; +} + #define DVMA_SIZE 0x4000
/* diff --git a/include/drivers/drivers.h b/include/drivers/drivers.h index 59ee436..85a8db0 100644 --- a/include/drivers/drivers.h +++ b/include/drivers/drivers.h @@ -73,7 +73,8 @@ void ss5_init(uint64_t base);
/* drivers/iommu.c */ void ob_init_iommu(uint64_t base); -void *dvma_alloc(int size, unsigned int *pphys); +void *dvma_alloc(int size); +unsigned int dvma_map_in(unsigned char *va);
/* drivers/sbus.c */ extern uint16_t graphic_depth;
This is to enable us to use its functions for the upcoming DMA functionality.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc32/lib.c | 2 +- arch/sparc32/ofmem_sparc32.c | 2 +- {arch => include/arch}/sparc32/pgtsrmmu.h | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename {arch => include/arch}/sparc32/pgtsrmmu.h (100%)
diff --git a/arch/sparc32/lib.c b/arch/sparc32/lib.c index a53a396..e88c0bf 100644 --- a/arch/sparc32/lib.c +++ b/arch/sparc32/lib.c @@ -11,7 +11,7 @@ #include "libopenbios/bindings.h" #include "arch/sparc32/ofmem_sparc32.h" #include "asm/asi.h" -#include "pgtsrmmu.h" +#include "arch/sparc32/pgtsrmmu.h" #include "openprom.h" #include "libopenbios/sys_info.h" #include "boot.h" diff --git a/arch/sparc32/ofmem_sparc32.c b/arch/sparc32/ofmem_sparc32.c index f7af753..9ac7fe0 100644 --- a/arch/sparc32/ofmem_sparc32.c +++ b/arch/sparc32/ofmem_sparc32.c @@ -17,7 +17,7 @@ #include "libc/string.h" #include "arch/sparc32/ofmem_sparc32.h" #include "asm/asi.h" -#include "pgtsrmmu.h" +#include "arch/sparc32/pgtsrmmu.h"
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
diff --git a/arch/sparc32/pgtsrmmu.h b/include/arch/sparc32/pgtsrmmu.h similarity index 100% rename from arch/sparc32/pgtsrmmu.h rename to include/arch/sparc32/pgtsrmmu.h
This is required for ensuring that CPU memory is coherent after DMA operations have completed.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/iommu.c | 14 ++++++++++++++ include/drivers/drivers.h | 1 + 2 files changed, 15 insertions(+)
diff --git a/drivers/iommu.c b/drivers/iommu.c index b8ec09e..c414894 100644 --- a/drivers/iommu.c +++ b/drivers/iommu.c @@ -10,6 +10,8 @@ #include "drivers/drivers.h" #include "iommu.h" #include "arch/sparc32/ofmem_sparc32.h" +#include "arch/sparc32/asi.h" +#include "arch/sparc32/pgtsrmmu.h"
#ifdef CONFIG_DEBUG_IOMMU #define DPRINTF(fmt, args...) \ @@ -81,6 +83,18 @@ dvma_alloc(int size) return va; }
+void +dvma_sync(unsigned char *va, int size) +{ + /* Synchronise the VA address region after DMA */ + unsigned long virt = pointer2cell(va); + unsigned long page; + + for (page = (unsigned long)virt; page < virt + size; page += PAGE_SIZE) { + srmmu_flush_tlb_page(page); + } +} + unsigned int dvma_map_in(unsigned char *va) { diff --git a/include/drivers/drivers.h b/include/drivers/drivers.h index 85a8db0..64824e4 100644 --- a/include/drivers/drivers.h +++ b/include/drivers/drivers.h @@ -74,6 +74,7 @@ void ss5_init(uint64_t base); /* drivers/iommu.c */ void ob_init_iommu(uint64_t base); void *dvma_alloc(int size); +void dvma_sync(unsigned char *va, int size); unsigned int dvma_map_in(unsigned char *va);
/* drivers/sbus.c */
Use Forth wrappers around the existing C functions to implement all the dma-* words in the root package.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc32/openbios.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- arch/sparc32/tree.fs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/arch/sparc32/openbios.c b/arch/sparc32/openbios.c index dd31c23..3ec8fd7 100644 --- a/arch/sparc32/openbios.c +++ b/arch/sparc32/openbios.c @@ -806,6 +806,43 @@ static void init_memory(void) PUSH(virt + MEMORY_SIZE); }
+/* ( size -- virt ) */ +static void +dma_alloc(void) +{ + ucell size = POP(); + unsigned long *va; + + va = dvma_alloc(size); + + PUSH(pointer2cell(va)); +} + +/* ( virt devaddr size -- ) */ +static void +dma_sync(void) +{ + ucell size = POP(); + POP(); + ucell virt = POP(); + + dvma_sync(cell2pointer(virt), size); +} + +/* ( virt size cacheable? -- devaddr ) */ +static void +dma_map_in(void) +{ + unsigned int iova; + + POP(); + POP(); + ucell virt = POP(); + + iova = dvma_map_in(cell2pointer(virt)); + PUSH((ucell)iova); +} + static void arch_init( void ) { @@ -839,6 +876,14 @@ arch_init( void ) modules_init(); ob_init_mmu(); ob_init_iommu(hwdef->iommu_base); + + bind_func("(sparc32-dma-alloc)", dma_alloc); + feval("['] (sparc32-dma-alloc) to (dma-alloc)"); + bind_func("(sparc32-dma-sync)", dma_sync); + feval("['] (sparc32-dma-sync) to (dma-sync)"); + bind_func("(sparc32-dma-map-in)", dma_map_in); + feval("['] (sparc32-dma-map-in) to (dma-map-in)"); + #ifdef CONFIG_DRIVER_OBIO mem_size = fw_cfg_read_i32(FW_CFG_RAM_SIZE); ob_obio_init(hwdef->slavio_base, hwdef->fd_offset, @@ -916,7 +961,7 @@ arch_init( void ) bind_func("platform-boot", boot ); bind_func("(arch-go)", setup_romvec ); - + /* Set up other properties */ push_str("/chosen"); fword("find-device"); diff --git a/arch/sparc32/tree.fs b/arch/sparc32/tree.fs index c82bb17..fc95636 100644 --- a/arch/sparc32/tree.fs +++ b/arch/sparc32/tree.fs @@ -1,5 +1,21 @@ include config.fs
+\ --------- +\ DMA words +\ --------- + +: sparc32-dma-free ( virt size -- ) + 2drop +; + +: sparc32-dma-map-out ( virt devaddr size -- ) + (dma-sync) +; + +['] sparc32-dma-free to (dma-free) +['] sparc32-dma-map-out to (dma-map-out) + + " /" find-device 2 encode-int " #address-cells" property 1 encode-int " #size-cells" property @@ -10,6 +26,26 @@ include config.fs : encode-unit encode-unit-sbus ; : decode-unit decode-unit-sbus ;
+ : dma-sync + (dma-sync) + ; + + : dma-alloc + (dma-alloc) + ; + + : dma-free + (dma-free) + ; + + : dma-map-in + (dma-map-in) + ; + + : dma-map-out + (dma-map-out) + ; + new-device " memory" device-name external
Implement flush_dcache_range() similar to flush_icache_range() in preparation for adding dma command support.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/ppc/qemu/kernel.h | 1 + arch/ppc/qemu/start.S | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+)
diff --git a/arch/ppc/qemu/kernel.h b/arch/ppc/qemu/kernel.h index fe9be83..3e25a56 100644 --- a/arch/ppc/qemu/kernel.h +++ b/arch/ppc/qemu/kernel.h @@ -21,6 +21,7 @@ extern void exit( int status ) __attribute__ ((noreturn));
/* start.S */ extern void flush_icache_range( char *start, char *stop ); +extern void flush_dcache_range( char *start, char *stop ); extern char of_rtas_start[], of_rtas_end[]; extern void call_elf( unsigned long arg1, unsigned long arg2, unsigned long elf_entry );
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index fed1b55..c679230 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -660,6 +660,27 @@ _GLOBAL(flush_icache_range): isync blr
+/* flush_dcache_range( unsigned long start, unsigned long stop) */ +_GLOBAL(flush_dcache_range): + li r5,CACHE_LINE_SIZE-1 + andc r3,r3,r5 + subf r4,r3,r4 + add r4,r4,r5 + srwi. r4,r4,LG_CACHE_LINE_SIZE + beqlr + mtctr r4 + mr r6,r3 +1: dcbst 0,r3 + addi r3,r3,CACHE_LINE_SIZE + bdnz 1b + sync /* wait for dcbst's to get to ram */ + mtctr r4 +2: dcbi 0,r6 + addi r6,r6,CACHE_LINE_SIZE + bdnz 2b + sync + blr + /* Get RAM size from QEMU configuration device */
#define CFG_ADDR 0xf0000510
Implement the dma-* words in the root node using Forth, except for dma-alloc and dma-sync which require C to use the in-built aligned memory allocator and I-cache and D-cache flushing.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/ppc/qemu/init.c | 35 +++++++++++++++++++++++++++++++++++ arch/ppc/qemu/tree.fs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index 8524750..74a4c6b 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -751,6 +751,35 @@ static void adler32(void) RET(s2 << 16 | s1); }
+/* ( size -- virt ) */ +static void +dma_alloc(void) +{ + ucell size = POP(); + ucell addr; + int ret; + + ret = ofmem_posix_memalign((void *)&addr, size, PAGE_SIZE); + + if (ret) { + PUSH(0); + } else { + PUSH(addr); + } +} + +/* ( virt devaddr size -- ) */ +static void +dma_sync(void) +{ + ucell size = POP(); + POP(); + ucell virt = POP(); + + flush_dcache_range(cell2pointer(virt), cell2pointer(virt + size)); + flush_icache_range(cell2pointer(virt), cell2pointer(virt + size)); +} + void arch_of_init(void) { @@ -768,6 +797,12 @@ arch_of_init(void) openbios_init(); modules_init(); setup_timers(); + + bind_func("ppc-dma-alloc", dma_alloc); + feval("['] ppc-dma-alloc to (dma-alloc)"); + bind_func("ppc-dma-sync", dma_sync); + feval("['] ppc-dma-sync to (dma-sync)"); + #ifdef CONFIG_DRIVER_PCI ob_pci_init(); #endif diff --git a/arch/ppc/qemu/tree.fs b/arch/ppc/qemu/tree.fs index 5b6bbc6..481acd9 100644 --- a/arch/ppc/qemu/tree.fs +++ b/arch/ppc/qemu/tree.fs @@ -7,6 +7,26 @@
include config.fs
+\ --------- +\ DMA words +\ --------- + +: ppc-dma-free ( virt size -- ) + 2drop +; + +: ppc-dma-map-in ( virt size cacheable? -- devaddr ) + 2drop +; + +: ppc-dma-map-out ( virt devaddr size -- ) + (dma-sync) +; + +['] ppc-dma-free to (dma-free) +['] ppc-dma-map-in to (dma-map-in) +['] ppc-dma-map-out to (dma-map-out) + \ ------------------------------------------------------------- \ device-tree \ ------------------------------------------------------------- @@ -18,6 +38,26 @@ include config.fs 1 encode-int " #size-cells" property h# 05f5e100 encode-int " clock-frequency" property
+ : dma-sync + (dma-sync) + ; + + : dma-alloc + (dma-alloc) + ; + + : dma-free + (dma-free) + ; + + : dma-map-in + (dma-map-in) + ; + + : dma-map-out + (dma-map-out) + ; + new-device " cpus" device-name 1 encode-int " #address-cells" property
Implement the dma-* words in the root node using Forth, except for dma-alloc and dma-sync which require C to use the in-built aligned memory allocator and MMU flushing.
Note that as OpenBIOS doesn't enable the IOMMU for SPARC64 it is possible to use the aligned memory allocator directly without any extra support code.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc64/openbios.c | 40 ++++++++++++++++++++++++++++++++++++++++ arch/sparc64/tree.fs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+)
diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c index 46d44ea..e9e08fd 100644 --- a/arch/sparc64/openbios.c +++ b/arch/sparc64/openbios.c @@ -722,6 +722,40 @@ static void init_memory(void) PUSH(virt + MEMORY_SIZE); }
+/* ( size -- virt ) */ +static void +dma_alloc(void) +{ + ucell size = POP(); + ucell addr; + int ret; + + /* OpenBIOS doesn't enable the sun4u IOMMU so we can fall back to + * using ofmem_posix_memalign */ + ret = ofmem_posix_memalign((void *)&addr, size, PAGE_SIZE); + + if (ret) { + PUSH(0); + } else { + PUSH(addr); + } +} + +/* ( virt devaddr size -- ) */ +static void +dma_sync(void) +{ + ucell size = POP(); + POP(); + ucell virt = POP(); + ucell va; + + for (va = virt; va < virt + size; va += PAGE_SIZE_8K) { + itlb_demap(va); + dtlb_demap(va); + } +} + extern volatile uint64_t *obp_ticks_pointer;
static void @@ -729,6 +763,12 @@ arch_init( void ) { openbios_init(); modules_init(); + + bind_func("sparc64-dma-alloc", dma_alloc); + feval("['] sparc64-dma-alloc to (dma-alloc)"); + bind_func("sparc64-dma-sync", dma_sync); + feval("['] sparc64-dma-sync to (dma-sync)"); + #ifdef CONFIG_DRIVER_PCI ob_pci_init();
diff --git a/arch/sparc64/tree.fs b/arch/sparc64/tree.fs index e034b59..a1d5620 100644 --- a/arch/sparc64/tree.fs +++ b/arch/sparc64/tree.fs @@ -19,6 +19,30 @@ include config.fs rot pocket tohexstr r> tmpstrcat drop ;
+\ --------- +\ DMA words +\ --------- + +: sparc64-dma-free ( virt size -- ) + 2drop +; + +: sparc64-dma-map-in ( virt size cacheable? -- devaddr ) + 2drop +; + +: sparc64-dma-map-out ( virt devaddr size -- ) + (dma-sync) +; + +['] sparc64-dma-free to (dma-free) +['] sparc64-dma-map-in to (dma-map-in) +['] sparc64-dma-map-out to (dma-map-out) + +\ ------------------------------------------------------------- +\ device-tree +\ ------------------------------------------------------------- + " /" find-device 2 encode-int " #address-cells" property 2 encode-int " #size-cells" property @@ -27,6 +51,29 @@ include config.fs : encode-unit encode-unit-upa ; : decode-unit decode-unit-upa ;
+ : dma-sync ( virt devaddr size -- ) + s" (dma-sync)" $find if execute then + ; + + : dma-alloc ( size -- virt ) + \ OpenBIOS doesn't enable the sun4u IOMMU so we can fall back to using + \ alloc-mem + h# 2000 + alloc-mem dup + h# 2000 1 - and - \ align to 8K page size + ; + + : dma-free ( virt size -- ) + 2drop + ; + + : dma-map-in ( virt size cacheable? -- devaddr ) + 2drop + ; + + : dma-map-out ( virt devaddr size -- ) + dma-sync + ; + new-device " memory" device-name " memory" device-type
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/macio.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/macio.c b/drivers/macio.c index fe19091..94ca90f 100644 --- a/drivers/macio.c +++ b/drivers/macio.c @@ -268,6 +268,7 @@ ob_macio_keylargo_init(const char *path, phys_addr_t addr) { phandle_t aliases;
+ REGISTER_NODE(ob_macio); aliases = find_dev("/aliases"); set_property(aliases, "mac-io", path, strlen(path) + 1);
This enables disk drivers to call the dma-* words as required by the specification, and in particular fixes the failing dma-alloc warnings emitted by NetBSD PPC on boot.
Note that we also add these methods to any partition/file packages via a new is-call-parent helper word to ensure that the dma-* words are available at all levels of interposition.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/ide.c | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/macio.c | 35 +++++++++++++++++++++++++++++++++++ drivers/pci.c | 40 ++++++++++++++++++++++++++++++++++++++++ forth/util/util.fs | 9 +++++++++ packages/disk-label.fs | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 163 insertions(+)
diff --git a/drivers/ide.c b/drivers/ide.c index a3535d8..274236f 100644 --- a/drivers/ide.c +++ b/drivers/ide.c @@ -1287,6 +1287,36 @@ ob_ide_close(struct ide_drive *drive) selfword("close-deblocker"); }
+static void +ob_ide_dma_alloc(int *idx) +{ + call_parent_method("dma-alloc"); +} + +static void +ob_ide_dma_free(int *idx) +{ + call_parent_method("dma-free"); +} + +static void +ob_ide_dma_map_in(int *idx) +{ + call_parent_method("dma-map-in"); +} + +static void +ob_ide_dma_map_out(int *idx) +{ + call_parent_method("dma-map-out"); +} + +static void +ob_ide_dma_sync(int *idx) +{ + call_parent_method("dma-sync"); +} + NODE_METHODS(ob_ide) = { { NULL, ob_ide_initialize }, { "open", ob_ide_open }, @@ -1294,6 +1324,11 @@ NODE_METHODS(ob_ide) = { { "read-blocks", ob_ide_read_blocks }, { "block-size", ob_ide_block_size }, { "max-transfer", ob_ide_max_transfer }, + { "dma-alloc", ob_ide_dma_alloc }, + { "dma-free", ob_ide_dma_free }, + { "dma-map-in", ob_ide_dma_map_in }, + { "dma-map-out", ob_ide_dma_map_out }, + { "dma-sync", ob_ide_dma_sync }, };
static void @@ -1318,6 +1353,11 @@ ob_ide_ctrl_decodeunit(int *idx) NODE_METHODS(ob_ide_ctrl) = { { NULL, ob_ide_ctrl_initialize }, { "decode-unit", ob_ide_ctrl_decodeunit }, + { "dma-alloc", ob_ide_dma_alloc }, + { "dma-free", ob_ide_dma_free }, + { "dma-map-in", ob_ide_dma_map_in }, + { "dma-map-out", ob_ide_dma_map_out }, + { "dma-sync", ob_ide_dma_sync }, };
static void set_cd_alias(const char *path) diff --git a/drivers/macio.c b/drivers/macio.c index 94ca90f..8ca20d8 100644 --- a/drivers/macio.c +++ b/drivers/macio.c @@ -220,9 +220,44 @@ ob_macio_encode_unit(void *private) push_str(buf); }
+static void +ob_macio_dma_alloc(int *idx) +{ + call_parent_method("dma-alloc"); +} + +static void +ob_macio_dma_free(int *idx) +{ + call_parent_method("dma-free"); +} + +static void +ob_macio_dma_map_in(int *idx) +{ + call_parent_method("dma-map-in"); +} + +static void +ob_macio_dma_map_out(int *idx) +{ + call_parent_method("dma-map-out"); +} + +static void +ob_macio_dma_sync(int *idx) +{ + call_parent_method("dma-sync"); +} + NODE_METHODS(ob_macio) = { { "decode-unit", ob_macio_decode_unit }, { "encode-unit", ob_macio_encode_unit }, + { "dma-alloc", ob_macio_dma_alloc }, + { "dma-free", ob_macio_dma_free }, + { "dma-map-in", ob_macio_dma_map_in }, + { "dma-map-out", ob_macio_dma_map_out }, + { "dma-sync", ob_macio_dma_sync }, };
static void diff --git a/drivers/pci.c b/drivers/pci.c index 295be7e..dbdd40e 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -428,6 +428,36 @@ ob_pci_bus_map_in(int *idx) PUSH(virt); }
+static void +ob_pci_dma_alloc(int *idx) +{ + call_parent_method("dma-alloc"); +} + +static void +ob_pci_dma_free(int *idx) +{ + call_parent_method("dma-free"); +} + +static void +ob_pci_dma_map_in(int *idx) +{ + call_parent_method("dma-map-in"); +} + +static void +ob_pci_dma_map_out(int *idx) +{ + call_parent_method("dma-map-out"); +} + +static void +ob_pci_dma_sync(int *idx) +{ + call_parent_method("dma-sync"); +} + NODE_METHODS(ob_pci_bus_node) = { { NULL, ob_pci_initialize }, { "open", ob_pci_open }, @@ -435,6 +465,11 @@ NODE_METHODS(ob_pci_bus_node) = { { "decode-unit", ob_pci_decode_unit }, { "encode-unit", ob_pci_encode_unit }, { "pci-map-in", ob_pci_bus_map_in }, + { "dma-alloc", ob_pci_dma_alloc }, + { "dma-free", ob_pci_dma_free }, + { "dma-map-in", ob_pci_dma_map_in }, + { "dma-map-out", ob_pci_dma_map_out }, + { "dma-sync", ob_pci_dma_sync }, };
/* ( pci-addr.lo pci-addr.mid pci-addr.hi size -- virt ) */ @@ -453,6 +488,11 @@ NODE_METHODS(ob_pci_bridge_node) = { { "decode-unit", ob_pci_decode_unit }, { "encode-unit", ob_pci_encode_unit }, { "pci-map-in", ob_pci_bridge_map_in }, + { "dma-alloc", ob_pci_dma_alloc }, + { "dma-free", ob_pci_dma_free }, + { "dma-map-in", ob_pci_dma_map_in }, + { "dma-map-out", ob_pci_dma_map_out }, + { "dma-sync", ob_pci_dma_sync }, };
NODE_METHODS(ob_pci_simple_node) = { diff --git a/forth/util/util.fs b/forth/util/util.fs index 6f549bf..8247c7d 100644 --- a/forth/util/util.fs +++ b/forth/util/util.fs @@ -60,6 +60,15 @@ is-func-end ;
+\ is-call-parent installs a function that calls a function with +\ the same name but on the parent node +: is-call-parent ( str len ) + 2dup is-func-begin + ['] (") , dup , ", null-align + ['] $call-parent , + is-func-end +; + \ ------------------------------------------------------------------------- \ install deblocker bindings \ ------------------------------------------------------------------------- diff --git a/packages/disk-label.fs b/packages/disk-label.fs index 8354f87..0021ade 100644 --- a/packages/disk-label.fs +++ b/packages/disk-label.fs @@ -75,6 +75,26 @@ new-device ( phandle probe-xt ) fs-handlers list-add , , ; + + : dma-alloc + " dma-alloc" $call-parent + ; + + : dma-free + " dma-free" $call-parent + ; + + : dma-map-in + " dma-map-in" $call-parent + ; + + : dma-map-out + " dma-map-out" $call-parent + ; + + : dma-sync + " dma-sync" $call-parent + ; finish-device
\ --------------------------------------------------------------------------- @@ -82,9 +102,27 @@ finish-device \ ---------------------------------------------------------------------------
device-end + +: initialise-partition-package ( -- ) + " dma-alloc" is-call-parent + " dma-free" is-call-parent + " dma-map-in" is-call-parent + " dma-map-out" is-call-parent + " dma-sync" is-call-parent +; + +: initialise-fs-package ( -- ) + " dma-alloc" is-call-parent + " dma-free" is-call-parent + " dma-map-in" is-call-parent + " dma-map-out" is-call-parent + " dma-sync" is-call-parent +; + : register-partition-package ( -- ) " register-part-handler" " disk-label" $find-package-method ?dup if active-package swap execute + initialise-partition-package else ." [disk-label] internal error" cr then @@ -93,6 +131,7 @@ device-end : register-fs-package ( -- ) " register-fs-handler" " disk-label" $find-package-method ?dup if active-package swap execute + initialise-fs-package else ." [misc-files] internal error" cr then
This enables disk drivers to call the dma-* words as required by the specification.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- arch/sparc32/tree.fs | 20 ++++++++++++++++++++ drivers/esp.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- drivers/iommu.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 3 deletions(-)
diff --git a/arch/sparc32/tree.fs b/arch/sparc32/tree.fs index fc95636..e9d0333 100644 --- a/arch/sparc32/tree.fs +++ b/arch/sparc32/tree.fs @@ -93,6 +93,11 @@ new-device : decode-unit decode-unit-sbus ; : map-in map-in-sbus ; : map-out map-out-sbus ; + : dma-alloc " dma-alloc" $call-parent ; + : dma-free " dma-free" $call-parent ; + : dma-map-in " dma-map-in" $call-parent ; + : dma-map-out " dma-map-out" $call-parent ; + : dma-sync " dma-sync" $call-parent ; finish-device
[IFDEF] CONFIG_BPP @@ -110,6 +115,11 @@ new-device external : encode-unit encode-unit-sbus ; : decode-unit decode-unit-sbus ; + : dma-alloc " dma-alloc" $call-parent ; + : dma-free " dma-free" $call-parent ; + : dma-map-in " dma-map-in" $call-parent ; + : dma-map-out " dma-map-out" $call-parent ; + : dma-sync " dma-sync" $call-parent ; finish-device
" /iommu/sbus" find-device @@ -119,6 +129,11 @@ new-device external : encode-unit encode-unit-sbus ; : decode-unit decode-unit-sbus ; + : dma-alloc " dma-alloc" $call-parent ; + : dma-free " dma-free" $call-parent ; + : dma-map-in " dma-map-in" $call-parent ; + : dma-map-out " dma-map-out" $call-parent ; + : dma-sync " dma-sync" $call-parent ; finish-device
" /iommu/sbus/ledma" find-device @@ -127,6 +142,11 @@ new-device " network" device-type h# 7 encode-int " busmaster-regval" property h# 26 encode-int 0 encode-int encode+ " intr" property + : dma-alloc " dma-alloc" $call-parent ; + : dma-free " dma-free" $call-parent ; + : dma-map-in " dma-map-in" $call-parent ; + : dma-map-out " dma-map-out" $call-parent ; + : dma-sync " dma-sync" $call-parent ; finish-device
\ obio (on-board IO) diff --git a/drivers/esp.c b/drivers/esp.c index 44b2096..0454d5c 100644 --- a/drivers/esp.c +++ b/drivers/esp.c @@ -248,6 +248,35 @@ inquiry(esp_private_t *esp, sd_private_t *sd) return 1; }
+static void +ob_esp_dma_alloc(__attribute__((unused)) esp_private_t **esp) +{ + call_parent_method("dma-alloc"); +} + +static void +ob_esp_dma_free(__attribute__((unused)) esp_private_t **esp) +{ + call_parent_method("dma-free"); +} + +static void +ob_esp_dma_map_in(__attribute__((unused)) esp_private_t **esp) +{ + call_parent_method("dma-map-in"); +} + +static void +ob_esp_dma_map_out(__attribute__((unused)) esp_private_t **esp) +{ + call_parent_method("dma-map-out"); +} + +static void +ob_esp_dma_sync(__attribute__((unused)) esp_private_t **esp) +{ + call_parent_method("dma-sync"); +}
static void ob_sd_read_blocks(sd_private_t **sd) @@ -333,6 +362,11 @@ NODE_METHODS(ob_sd) = { { "close", ob_sd_close }, { "read-blocks", ob_sd_read_blocks }, { "block-size", ob_sd_block_size }, + { "dma-alloc", ob_esp_dma_alloc }, + { "dma-free", ob_esp_dma_free }, + { "dma-map-in", ob_esp_dma_map_in }, + { "dma-map-out", ob_esp_dma_map_out }, + { "dma-sync", ob_esp_dma_sync }, };
@@ -443,9 +477,14 @@ ob_esp_encodeunit(__attribute__((unused)) esp_private_t **esp) }
NODE_METHODS(ob_esp) = { - { NULL, ob_esp_initialize }, - { "decode-unit", ob_esp_decodeunit }, - { "encode-unit", ob_esp_encodeunit }, + { NULL, ob_esp_initialize }, + { "decode-unit", ob_esp_decodeunit }, + { "encode-unit", ob_esp_encodeunit }, + { "dma-alloc", ob_esp_dma_alloc }, + { "dma-free", ob_esp_dma_free }, + { "dma-map-in", ob_esp_dma_map_in }, + { "dma-map-out", ob_esp_dma_map_out }, + { "dma-sync", ob_esp_dma_sync }, };
static void diff --git a/drivers/iommu.c b/drivers/iommu.c index c414894..a6c02b8 100644 --- a/drivers/iommu.c +++ b/drivers/iommu.c @@ -207,6 +207,36 @@ ob_iommu_map_out(void) ofmem_release_io(virt, size); }
+static void +ob_iommu_dma_alloc(void) +{ + call_parent_method("dma-alloc"); +} + +static void +ob_iommu_dma_free(void) +{ + call_parent_method("dma-free"); +} + +static void +ob_iommu_dma_map_in(void) +{ + call_parent_method("dma-map-in"); +} + +static void +ob_iommu_dma_map_out(void) +{ + call_parent_method("dma-map-out"); +} + +static void +ob_iommu_dma_sync(void) +{ + call_parent_method("dma-sync"); +} + void ob_init_iommu(uint64_t base) { @@ -234,4 +264,9 @@ ob_init_iommu(uint64_t base)
bind_func("map-in", ob_iommu_map_in); bind_func("map-out", ob_iommu_map_out); + bind_func("dma-alloc", ob_iommu_dma_alloc); + bind_func("dma-free", ob_iommu_dma_free); + bind_func("dma-map-in", ob_iommu_dma_map_in); + bind_func("dma-map-out", ob_iommu_dma_map_out); + bind_func("dma-sync", ob_iommu_dma_sync); }
Instead of using a C initialize function to create the esp device, switch over to using the Forth "new-device" word so that all of the initialisation can be done in place in ob_esp_init().
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/esp.c | 98 ++++++++++++++++++++++++++++------------------------------- 1 file changed, 47 insertions(+), 51 deletions(-)
diff --git a/drivers/esp.c b/drivers/esp.c index 0454d5c..b13ff2c 100644 --- a/drivers/esp.c +++ b/drivers/esp.c @@ -435,35 +435,6 @@ espdma_init(unsigned int slot, uint64_t base, unsigned long offset, }
static void -ob_esp_initialize(__attribute__((unused)) esp_private_t **esp) -{ - phandle_t ph = get_cur_dev(); - - set_int_property(ph, "#address-cells", 2); - set_int_property(ph, "#size-cells", 0); - - /* set device type */ - push_str("scsi"); - fword("device-type"); - - /* QEMU's ESP emulation does not support mixing DMA and FIFO messages. By - setting this attribute, we prevent the Solaris ESP kernel driver from - trying to use this feature when booting a disk image (and failing) */ - PUSH(0x58); - fword("encode-int"); - push_str("scsi-options"); - fword("property"); - - PUSH(0x24); - fword("encode-int"); - PUSH(0); - fword("encode-int"); - fword("encode+"); - push_str("intr"); - fword("property"); -} - -static void ob_esp_decodeunit(__attribute__((unused)) esp_private_t **esp) { fword("decode-unit-scsi"); @@ -477,7 +448,6 @@ ob_esp_encodeunit(__attribute__((unused)) esp_private_t **esp) }
NODE_METHODS(ob_esp) = { - { NULL, ob_esp_initialize }, { "decode-unit", ob_esp_decodeunit }, { "encode-unit", ob_esp_encodeunit }, { "dma-alloc", ob_esp_dma_alloc }, @@ -529,6 +499,53 @@ ob_esp_init(unsigned int slot, uint64_t base, unsigned long espoffset, return -1; }
+ push_str("/iommu/sbus/espdma"); + fword("find-device"); + fword("new-device"); + + push_str("esp"); + fword("device-name"); + + /* set device type */ + push_str("scsi"); + fword("device-type"); + + /* QEMU's ESP emulation does not support mixing DMA and FIFO messages. By + setting this attribute, we prevent the Solaris ESP kernel driver from + trying to use this feature when booting a disk image (and failing) */ + PUSH(0x58); + fword("encode-int"); + push_str("scsi-options"); + fword("property"); + + PUSH(0x24); + fword("encode-int"); + PUSH(0); + fword("encode-int"); + fword("encode+"); + push_str("intr"); + fword("property"); + + PUSH(slot); + fword("encode-int"); + PUSH(espoffset); + fword("encode-int"); + fword("encode+"); + PUSH(0x00000010); + fword("encode-int"); + fword("encode+"); + push_str("reg"); + fword("property"); + + PUSH(0x02625a00); + fword("encode-int"); + push_str("clock-frequency"); + fword("property"); + + REGISTER_NODE_METHODS(ob_esp, "/iommu/sbus/espdma/esp"); + + fword("finish-device"); + esp->buffer = (void *)dvma_alloc(BUFSIZE); esp->buffer_dvma = dvma_map_in(esp->buffer); if (!esp->buffer || !esp->buffer_dvma) { @@ -568,27 +585,6 @@ ob_esp_init(unsigned int slot, uint64_t base, unsigned long espoffset, #endif }
- REGISTER_NAMED_NODE(ob_esp, "/iommu/sbus/espdma/esp"); - device_end(); - /* set reg */ - push_str("/iommu/sbus/espdma/esp"); - fword("find-device"); - PUSH(slot); - fword("encode-int"); - PUSH(espoffset); - fword("encode-int"); - fword("encode+"); - PUSH(0x00000010); - fword("encode-int"); - fword("encode+"); - push_str("reg"); - fword("property"); - - PUSH(0x02625a00); - fword("encode-int"); - push_str("clock-frequency"); - fword("property"); - for (id = 0; id < 8; id++) { if (!esp->sd[id].present) continue;
Use the proper IEEE-1275 dma words to allocate and map DMA memory.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/esp.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/esp.c b/drivers/esp.c index b13ff2c..0880ab2 100644 --- a/drivers/esp.c +++ b/drivers/esp.c @@ -476,6 +476,7 @@ ob_esp_init(unsigned int slot, uint64_t base, unsigned long espoffset, int id, diskcount = 0, cdcount = 0, *counter_ptr; char nodebuff[256], aliasbuff[256]; esp_private_t *esp; + ucell addr; unsigned int i;
DPRINTF("Initializing SCSI..."); @@ -546,8 +547,22 @@ ob_esp_init(unsigned int slot, uint64_t base, unsigned long espoffset,
fword("finish-device");
- esp->buffer = (void *)dvma_alloc(BUFSIZE); - esp->buffer_dvma = dvma_map_in(esp->buffer); + fword("my-self"); + push_str("/iommu/sbus/espdma/esp"); + feval("open-dev to my-self"); + PUSH(BUFSIZE); + feval("dma-alloc"); + addr = POP(); + esp->buffer = cell2pointer(addr); + + PUSH(addr); + PUSH(BUFSIZE); + PUSH(1); + feval("dma-map-in"); + addr = POP(); + esp->buffer_dvma = addr; + feval("to my-self"); + if (!esp->buffer || !esp->buffer_dvma) { DPRINTF("Can't get a DVMA buffer\n"); return -1;
On 21/05/18 22:33, Mark Cave-Ayland wrote:
This patchset is something I've been working on for a while and started off with the aim of getting rid of the "dma-alloc" console warnings whilst booting *BSD images on PPC, but ended up as a full implementation for SPARC32/SPARC64 and PPC.
The patchset is fairly straightfoward: the first few patches rework the SPARC32 DVMA functions to make them usable from Forth, whilst patch 8 adds a missing D-cache flush for PPC which could certainly do with another set of eyes.
The remainder of the patches add PPC and SPARC64 support before adding in the complete "dma-*" $call-parent chains to enable devices to call the DMA functions as indicated in the IEEE-1275 specification and various FCode examples found around the net.
Finally the last 2 patches switch the esp SCSI driver over to use the IEEE-1275 Forth words instead of calling the low-level C functions directly.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
Mark Cave-Ayland (15): dma: add defers for the dma-* words SPARC32: rename dvma_alloc()'s ba variable to iova SPARC32: allocate contiguous physical memory for DVMA SPARC32: implement dvma_map_in() for DMA IOVA to phys translation SPARC32: move pgtsrmmu.h from arch/sparc32 to include/arch/sparc32 SPARC32: implement dvma_sync() function for synchronising DMA memory SPARC32: implement dma-* words PPC: add flush_dcache_range() to start.S PPC: implement dma-* words SPARC64: implement dma-* words macio: add missing REGISTER_NODE for New World macio devices pci: add dma-* call-parent chain to all PCI devices and bridges sbus: add dma-* call-parent chain to all PCI devices and bridges esp: switch creation of esp device over to use new-device esp: switch over to using dma-alloc/dma-map-in
arch/ppc/qemu/init.c | 35 +++++++ arch/ppc/qemu/kernel.h | 1 + arch/ppc/qemu/start.S | 21 ++++ arch/ppc/qemu/tree.fs | 40 ++++++++ arch/sparc32/lib.c | 2 +- arch/sparc32/ofmem_sparc32.c | 2 +- arch/sparc32/openbios.c | 47 ++++++++- arch/sparc32/tree.fs | 56 +++++++++++ arch/sparc64/openbios.c | 40 ++++++++ arch/sparc64/tree.fs | 47 +++++++++ drivers/esp.c | 159 ++++++++++++++++++++---------- drivers/ide.c | 40 ++++++++ drivers/iommu.c | 95 +++++++++++++++--- drivers/macio.c | 36 +++++++ drivers/pci.c | 40 ++++++++ forth/device/other.fs | 8 +- forth/device/table.fs | 2 +- forth/util/util.fs | 9 ++ {arch => include/arch}/sparc32/pgtsrmmu.h | 0 include/drivers/drivers.h | 4 +- packages/disk-label.fs | 39 ++++++++ 21 files changed, 646 insertions(+), 77 deletions(-) rename {arch => include/arch}/sparc32/pgtsrmmu.h (100%)
No further comments, and this has passed all my local boot tests across SPARC32, SPARC64 and PPC so I've pushed it to master.
ATB,
Mark.