📄 proll.patch
字号:
+}++static int con_pread(__attribute__((unused)) int dev_desc, __attribute__((unused)) int offset, char *buf, unsigned int nbytes)+{+ unsigned int i;++ for(i = 0; i < nbytes; i ++) {+ buf[i] = obp_nbgetchar();+ }+ return nbytes;+}++static int con_pwrite(__attribute__((unused)) int dev_desc, __attribute__((unused)) int offset, char *buf, unsigned int nbytes)+{+ unsigned int i;++ for(i = 0; i < nbytes; i ++) {+ obp_nbputchar(buf[i]);+ }+ return nbytes;+}++#define isnum(c) ((c >= '0') && (c < '9'))+#define ctoi(c) (c - '0')++static int obp_devopen(char *str) {+#ifdef DEBUG_OBP+ printk("obp_devopen(%s)\n", str);+#endif+ if (str[0] == 's' && str[1] == 'd' && str[4] == ',') {+ unsigned int target;++ if (str[5] < 7)+ target = str[5];+ else if (isnum(str[6]) && isnum(str[5])) {+ target = (ctoi(str[5]) * 10 + ctoi(str[6])) & 7;+ }+ else {+ target = ctoi(str[5]) & 7;+ }+ fd_table[fd_index].unit = target;+ fd_table[fd_index].part = str[10] - 'a';+ fd_table[fd_index].pread = esp_pread;+ return fd_index++; // XXX+ }+ return 0;+}++static int obp_devclose(__attribute__((unused)) int dev_desc) {+#ifdef DEBUG_OBP+ printk("obp_devclose %d\n", dev_desc);+#endif+ fd_index--; // XXX+ return 0;+}++static int obp_rdblkdev(int dev_desc, int num_blks, int offset, char *buf)+{+#ifdef DEBUG_OBP+ printk("obp_rdblkdev: fd %d, num_blks %d, offset %d, buf 0x%x\n", dev_desc, num_blks, offset, buf);+#endif+ return fd_table[dev_desc].pread(dev_desc, offset, buf, num_blks * 512);+}++static char *obp_dumb_mmap(char *va, __attribute__((unused)) int which_io,+ unsigned int pa, unsigned int size)+{+ unsigned int npages;+ unsigned int off;+ unsigned int mva;++#ifdef DEBUG_OBP+ printk("obp_dumb_mmap: virta %x, which_io %d, paddr %x, sz %d\n", va, which_io, pa, size);+#endif+ off = pa & (PAGE_SIZE-1);+ npages = (off + size + (PAGE_SIZE-1)) / PAGE_SIZE;+ pa &= ~(PAGE_SIZE-1);++ mva = (unsigned int) va;+ while (npages-- != 0) {+ map_page(pmem.pl1, mva, pa, 1, pmem.pbas);+ mva += PAGE_SIZE;+ pa += PAGE_SIZE;+ }+ return va;+}++static void obp_dumb_munmap(__attribute__((unused)) char *va,+ __attribute__((unused)) unsigned int size)+{+#ifdef DEBUG_OBP+ printk("obp_dumb_munmap: virta %x, sz %d\n", va, size);+#endif+}++static int obp_devread(int dev_desc, char *buf, int nbytes)+{+ int ret;+#ifdef DEBUG_OBP+ printk("obp_devread: fd %d, nbytes %d\n", dev_desc, nbytes);+#endif+ ret = fd_table[dev_desc].pread(dev_desc, fd_table[dev_desc].offset, buf, nbytes);+ fd_table[dev_desc].offset += nbytes;+ return ret;+}++static int obp_devwrite(int dev_desc, char *buf, int nbytes)+{+ int ret;+#ifdef DEBUG_OBP+ printk("obp_devwrite: fd %d, buf %s, nbytes %d\n", dev_desc, buf, nbytes);+#endif+ ret = fd_table[dev_desc].pwrite(dev_desc, fd_table[dev_desc].offset, buf, nbytes);+ fd_table[dev_desc].offset += nbytes;+ return ret;+}++static int obp_devseek(int dev_desc, __attribute__((unused)) int hi, int lo)+{+#ifdef DEBUG_OBP+ printk("obp_devseek: fd %d, hi %d, lo %d\n", dev_desc, hi, lo);+#endif+ fd_table[dev_desc].offset = lo;+ return 0;+}++static int obp_inst2pkg(int dev_desc)+{+#ifdef DEBUG_OBP+ printk("obp_inst2pkg: fd %d\n", dev_desc);+#endif+ return fd_table[dev_desc].unit;+}diff -ruN proll_18.orig/qemu/system_qemu.c proll-patch-15/qemu/system_qemu.c--- proll_18.orig/qemu/system_qemu.c 1970-01-01 00:00:00.000000000 +0000+++ proll-patch-15/qemu/system_qemu.c 2005-04-16 06:16:20.000000000 +0000@@ -0,0 +1,430 @@+/**+ ** Proll (PROM replacement)+ ** system.c: shared miscallenea.+ ** Copyright 1999 Pete Zaitcev+ ** This code is licensed under GNU General Public License.+ **/+#include <stdarg.h>+#include <asi.h>+#include <crs.h>+#ifndef NULL+#define NULL ((void*)0)+#endif++#include "pgtsrmmu.h"++#include "vconsole.h"+#include <timer.h> /* Local copy of 2.2 style include */+#include <general.h> /* __P() */+#include <net.h> /* init_net() */+#include <romlib.h> /* we are a provider for part of this. */+#include <netpriv.h> /* myipaddr */+#include <arpa.h>+#include <system.h> /* our own prototypes */++/*+ * We export this.+ */+char idprom[IDPROM_SIZE];+++/*+ * Create an I/O mapping to pa[size].+ * Returns va of the mapping or 0 if unsuccessful.+ */+void *+map_io(unsigned pa, int size)+{+ void *va;+ unsigned int npages;+ unsigned int off;+ unsigned int mva;++ off = pa & (PAGE_SIZE-1);+ npages = (off + size + (PAGE_SIZE-1)) / PAGE_SIZE;+ pa &= ~(PAGE_SIZE-1);++ va = mem_alloc(&cio, npages*PAGE_SIZE, PAGE_SIZE);+ if (va == 0) return va;++ mva = (unsigned int) va;+ /* printk("map_io: va 0x%x pa 0x%x off 0x%x npages %d\n", va, pa, off, npages); */ /* P3 */+ while (npages-- != 0) {+ map_page(pmem.pl1, mva, pa, 1, pmem.pbas);+ mva += PAGE_SIZE;+ pa += PAGE_SIZE;+ }++ return (void *)((unsigned int)va + off);+}++/*+ * Tablewalk routine used for testing.+ * Returns PTP/PTE.+ */+unsigned int+proc_tablewalk(int ctx, unsigned int va)+{+ unsigned int pa1;++ __asm__ __volatile__ ("lda [%1] %2, %0" :+ "=r" (pa1) :+ "r" (AC_M_CTPR), "i" (ASI_M_MMUREGS));+ /* printk(" ctpr %x ctx %x\n", pa1, ctx); */ /* P3 */+ pa1 <<= 4;+ pa1 = ld_bypass(pa1 + (ctx << 2));+ if ((pa1 & 0x03) == 0) goto invalid;+ return mem_tablewalk((pa1 & 0xFFFFFFF0) << 4, va);++invalid:+ printk(" invalid %x\n", pa1);+ return 0;+}++/*+ * Walk the tables in memory, starting at physical address pa.+ */+unsigned int+mem_tablewalk(unsigned int pa, unsigned int va)+{+ unsigned int pa1;++ printk("pa %x va %x", pa, va);+ pa1 = ld_bypass(pa + (((va&0xFF000000)>>24) << 2));+ if ((pa1 & 0x03) == 0) goto invalid;+ printk(" l1 %x", pa1);+ pa1 <<= 4; pa1 &= 0xFFFFFF00;+ pa1 = ld_bypass(pa1 + (((va&0x00FC0000)>>18) << 2));+ if ((pa1 & 0x03) == 0) goto invalid;+ printk(" l2 %x", pa1);+ pa1 <<= 4; pa1 &= 0xFFFFFF00;+ pa1 = ld_bypass(pa1 + (((va&0x0003F000)>>12) << 2));+ if ((pa1 & 0x03) == 0) goto invalid;+ printk(" l3 %x", pa1);+ printk(" off %x\n", va&0x00000FFF);+ return pa1;+invalid:+ printk(" invalid %x\n", pa1);+ return 0;+}++/*+ * Make CPU page tables.+ * Returns pointer to context table.+ * Here we ignore memory allocation errors which "should not happen"+ * because we cannot print anything anyways if memory initialization fails.+ */+void makepages(struct phym *t, unsigned int highbase)+{+ unsigned int *ctp, *l1, pte;+ int i;+ unsigned int pa, va;++ ctp = mem_zalloc(&cmem, NCTX_SWIFT*sizeof(int), NCTX_SWIFT*sizeof(int));+ l1 = mem_zalloc(&cmem, 256*sizeof(int), 256*sizeof(int));++ pte = SRMMU_ET_PTD | (((unsigned int)l1 - PROLBASE + highbase) >> 4);+ for (i = 0; i < NCTX_SWIFT; i++) {+ ctp[i] = pte;+ }++ pa = PROLBASE;+ for (va = PROLBASE; va < PROLDATA; va += PAGE_SIZE) {+ map_page(l1, va, pa, 0, highbase);+ pa += PAGE_SIZE;+ }+ pa = highbase + PROLDATA - PROLBASE;+ for (va = PROLDATA; va < PROLBASE + PROLSIZE; va += PAGE_SIZE) {+ map_page(l1, va, pa, 0, highbase);+ pa += PAGE_SIZE;+ }++ /* We need to start from LOADBASE, but kernel wants PAGE_SIZE. */+ pa = 0;+ for (va = 0; va < LOWMEMSZ; va += PAGE_SIZE) {+ map_page(l1, va, pa, 0, highbase);+ pa += PAGE_SIZE;+ }++ t->pctp = ctp;+ t->pl1 = l1;+ t->pbas = highbase;+}++/*+ * Create a memory mapping from va to epa in page table pgd.+ * highbase is used for v2p translation.+ */+int+map_page(unsigned int *pgd, unsigned int va,+ unsigned int epa, int type, unsigned int highbase)+{+ unsigned int pte;+ unsigned int *p;+ unsigned int pa;++ pte = pgd[((va)>>SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD-1)];+ if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) {+ p = mem_zalloc(&cmem, SRMMU_PTRS_PER_PMD*sizeof(int),+ SRMMU_PTRS_PER_PMD*sizeof(int));+ if (p == 0) goto drop;+ pte = SRMMU_ET_PTD |+ (((unsigned int)p - PROLBASE + highbase) >> 4);+ pgd[((va)>>SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD-1)] = pte;+ /* barrier() */+ }++ pa = ((pte & 0xFFFFFFF0) << 4);+ pa += (((va)>>SRMMU_PMD_SHIFT & (SRMMU_PTRS_PER_PMD-1)) << 2);+ pte = ld_bypass(pa);+ if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) {+ p = mem_zalloc(&cmem, SRMMU_PTRS_PER_PTE*sizeof(int),+ SRMMU_PTRS_PER_PTE*sizeof(int));+ if (p == 0) goto drop;+ pte = SRMMU_ET_PTD |+ (((unsigned int)p - PROLBASE + highbase) >> 4);+ st_bypass(pa, pte);+ }++ pa = ((pte & 0xFFFFFFF0) << 4);+ pa += (((va)>>PAGE_SHIFT & (SRMMU_PTRS_PER_PTE-1)) << 2);++ pte = SRMMU_ET_PTE | ((epa & PAGE_MASK) >> 4);+ if (type) { /* I/O */+ pte |= SRMMU_REF;+ /* SRMMU cannot make Supervisor-only, but not exectutable */+ pte |= SRMMU_PRIV;+ } else { /* memory */+ pte |= SRMMU_REF|SRMMU_CACHE;+ pte |= SRMMU_PRIV; /* Supervisor only access */+ }+ st_bypass(pa, pte);+ return 0;++drop:+ return -1;+}++/*+ * Switch page tables.+ */+void+init_mmu_swift(unsigned int ctp_phy)+{+ unsigned int addr;++ /*+ * Flush cache+ */+ for (addr = 0; addr < 0x2000; addr += 0x10) {+ __asm__ __volatile__ ("sta %%g0, [%0] %1\n\t" : :+ "r" (addr), "i" (ASI_M_DATAC_TAG));+ __asm__ __volatile__ ("sta %%g0, [%0] %1\n\t" : :+ "r" (addr<<1), "i" (ASI_M_TXTC_TAG));+ }++ /*+ * Switch ctx table+ */+ ctp_phy >>= 4;+ /* printk("done flushing, switching to %x\n", ctp_phy); */+ __asm__ __volatile__ ("sta %0, [%1] %2\n\t" : :+ "r" (ctp_phy), "r" (AC_M_CTPR), "i" (ASI_M_MMUREGS));++ /*+ * Flush old page table references+ */+ __asm__ __volatile__ ("sta %%g0, [%0] %1\n\t" : :+ "r" (0x400), "i" (ASI_M_FLUSH_PROBE) : "memory");+}++/*+ * add_timer, del_timer+ * This should go into sched.c, but we have it split for different archs.+ */+struct timer_list_head {+ struct timer_list *head, *tail;+};++static struct timer_list_head timers; /* Anonymous heap of timers */++void add_timer(struct timer_list *timer) {+ struct timer_list *p;+ if (timer->prev != NULL || timer->next != NULL) {+ printk("bug: kernel timer added twice at 0x%x.\n",+ __builtin_return_address(0));+ return;+ }+ if ((p = timers.tail) != NULL) {+ timer->prev = p;+ p->next = timer;+ timers.tail = timer;+ } else {+ timers.head = timer;+ timers.tail = timer;+ }+ return;+}++int del_timer(struct timer_list *timer) {+ struct timer_list *p;+ int ret;++ if (timers.head == timer) timers.head = timer->next;+ if (timers.tail == timer) timers.tail = timer->prev;+ if ((p = timer->prev) != NULL) p->next = timer->next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -